# coding:utf-8

前端组件数据库对象_obj=None
后端组件数据库对象_obj=None
import socket
import tornado.web                          #第三方模块tornado       需要下载  web小型框架 使用IO多路复用
import tornado.ioloop                       #第三方模块tornado       需要下载  web小型框架 使用IO多路复用
import os,sys,json                          #内置标准库              os文件操作、sys系统操作、json数据类型
import yaml                                 #第三方模块yaml          需要下载  是一个配置文件解析的第三方模块
from tornado.websocket import WebSocketHandler
sys.path.append(os.path.dirname(os.path.abspath(__file__)))           #将项目路径添加到环境中   使得python可以导包
pro=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

print("pro",pro)
sys.path.append(pro)
sys.path.append(pro+os.sep+'python')
from other import parse                     #导包                   项目路径/other/parse.py
from other.other import my_js,base_vue_template              #导包                   项目路径/other/parse.py
from db.tool_sqlite2 import *               #导包                   项目路径/db/tool_sqlite2.py  下的变量以及函数
import shutil
from db.yaml_config import yaml_config
from project_python.edit import auto_config
from project_python.edit import num_dct as config_dct_data_
import urllib.parse
import base64  
from io import BytesIO  
import time  
import re
from _base_tool.python.template_create import template_create
from project_python.db.tool_sqlite2 import base_db
from _base_tool.python.根据树结构流程字典运行流程 import flow_eee
from _base_tool.python.解析yaml配置文件中的页面数据_将之转为html import tohtml
from _base_tool.python.生成默认需要的js和css import test as ttest
from _base_tool.python.获取基础组件 import 获取后端基础组件,获取前端基础组件,获取目录1的结构数据,获取目录2的结构数据,获取组件的结构数据
后端基础组件内容=获取后端基础组件()
前端基础组件内容=获取前端基础组件()

新项目初始内容={
    #项目名称
    "project_name":"",
    #数据库 数据库数据
    "db_config": {
        'base_info':{"index":2,},"dict":{
            "1":{
                "base_info":{
                        "vue_name":"a_1_0_2_26_1",
                        "index":0,
                        "deepcopy_data":{"name":'数据库列表'}
                        },
                "dict":{}
            },
            # "2":{
            #     "base_info":{
            #             "vue_name":"a_1_0_2_27_1",
            #             "index":0,
            #             "deepcopy_data":{"name":'搜索数据库'}
            #             },
            #     "dict":{}
            # },
        }
        
    },
    #前端 页面数据
    "page_config": {
        'base_info':{"index":3,},"dict":{
            "1":{
                "base_info":{
                        "vue_name":"a_1_0_2_30_1",
                        "index":0,
                        "deepcopy_data":{"name":'页面列表'}
                        },
                "dict":{}
            },
            "2":前端基础组件内容,
            "3":{
                "base_info":{
                        "vue_name":"a_1_0_2_32_1",
                        "index":0,
                        "deepcopy_data":{"name":'静态文件夹'}
                        },
                "dict":{}
            },
        }
        
    },
    #后端 流程图数据
    "flow_chat_config": {
        'base_info':{"index":2,},"dict":{
            "1":{
                "base_info":{
                        "vue_name":"a_1_0_2_6_1",
                        "index":0,
                        "deepcopy_data":{"name":'流程列表'},
                        },
                "dict":{}
            },
            "2":后端基础组件内容
        }
        
    },
    #组件库 数据
    "template_config": {
            'base_info':{"index":3,},"dict":{
            "1":{
                "base_info":{
                        "vue_name":"a_1_0_2_0_0_lines",
                        "index":0,
                        "deepcopy_data":{"name":'我的组件库'}
                        },
                "dict":{
                    "1":{
                            "base_info":{
                                    "vue_name":"a_1_0_2_1_0",
                                    "index":0,
                                    "deepcopy_data":{"name":'我的前端组件库'}
                                    },
                            "dict":{}
                        },
                    "2":{
                            "base_info":{
                                    "vue_name":"a_1_0_2_0_0_lines",
                                    "index":0,
                                    "deepcopy_data":{"name":'我的后端组件库 '}
                                    },
                            "dict":{}
                        },
                    }
            },
            "2":{
                "base_info":{
                        "vue_name":"a_1_0_2_0_0_lines",
                        "index":0,
                        "deepcopy_data":{"name":'共享组件库'}
                        },
                "dict":{
                    
                    "1":{
                                 
                            "base_info":{
                                    "index":0,
                                    "vue_name":"a_1_0_2_0_0_lines",
                                    "deepcopy_data":{"name":'共享前端组件库',"icon1_show_flag":False,"click_obj":{'func':"编辑区显示控制.set",'args':['前端组件库_编辑栏']}}
                                    },
                            "dict":{}
                        },
                    "2":{
                            "base_info":{
                                    "index":0,
                                    "vue_name":"a_1_0_2_0_0_lines",
                                    "deepcopy_data":{"name":'共享后端组件库',"icon1_show_flag":False,"click_obj":{'func':"编辑区显示控制.set",'args':['后端组件库_编辑栏']}}
                                    },
                            "dict":{}
                        },
                    }
                },
            "3":{
                "base_info":{
                        "vue_name":"a_1_0_2_0_0_lines",
                        "index":0,
                        "deepcopy_data":{"name":'搜索'}
                        },
                "dict":{}
            },
            },
            
        },
    #当前正在运行的流程
    "run_flow":{},
    "process2_web_handle": {
        "ip": "127.0.0.1",
        "port": 9000
    },
}

def get_external_ip():  
    # 尝试获取网络接口上绑定的、可以从网络访问的IP地址  
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
    try:  
        # 不需要真正发送数据，只是获取本地主机名  
        s.connect(('8.8.8.8', 1))  # 连接到Google的公共DNS服务器  
        ip_address = s.getsockname()[0]  
    except Exception:  
        ip_address = socket.gethostbyname(socket.gethostname())  # 如果失败，则使用本地主机名  
    finally:  
        s.close()  
    return ip_address  
base_config={'project_dir_path':os.path.dirname(os.path.dirname(os.path.abspath(__file__)))}

base_config={}
def config_init():
    global base_config
    base_config['flow_dir']=pro+os.sep+os.sep+'_server'+os.sep+'flow_dir'
    base_config['process2_web_handle']={"ip": "127.0.0.1","port": 9000}
    base_config['base_vue_template']=pro+os.sep+os.sep+'_web'+os.sep+'base_vue_template'        #vue基础组件
    base_config['base_js_dir']=pro+os.sep+os.sep+'_web'+os.sep+'base_js'        #基础js
    base_config['base_css_dir']=pro+os.sep+os.sep+'_web'+os.sep+'base_css'        #基础css
    base_config['vue_template_store']=pro+os.sep+os.sep+'_web'+os.sep+'vue_template_store'       #vue组件商场
    base_config['static_dir']=pro+os.sep+os.sep+'_static_dir'    #存放静态文件的文件夹
    base_config['static_path']=r'static_base'#tornado静态路由格式 
    base_config['pro']=pro#项目根目录
    base_config['db_dir']=os.path.dirname(pro)+os.sep+"db_dir"#存放数据库数据
    base_config['user_db_file']=os.path.dirname(pro)+os.sep+"db_dir"#存放数据库数据-用户
    base_config['temp_dir']=os.path.dirname(pro)+os.sep+"temp_dir"#存放数据库数据-用户组件目录
    base_config['user_dir']=os.path.dirname(pro)+os.sep+"user_dir"#存放用户数据
    try:os.makedirs(base_config['user_db_file'])
    except:pass
    try:os.makedirs(base_config['temp_dir'])
    except:pass
    try:os.makedirs(base_config['user_dir'])
    except:pass
    base_config['login']=pro+os.sep+'_web'+os.sep+'web_html'+os.sep+"login.html"   #登录页面      
    base_config['project']=pro+os.sep+'_web'+os.sep+'web_html'+os.sep+"project.html"   #登录页面      
    base_config['home']=pro+os.sep+'_web'+os.sep+'web_html'+os.sep+"home.html"   #登录页面   
    base_config['test']=pro+os.sep+'_web'+os.sep+'web_html'  
    base_config['test2']=pro+os.sep+'_web'+os.sep+'web_html'+os.sep+"test2.html"   #登录页面    
config_init()
#用户登录验证
class user_db():
    login_timeout=30*60*60*24#30天
    db_obj=None
    #当前用户登录的数据   user
    now_user_login_info1={}#{用户id:随机分配的token}
    now_user_login_info2={}#{随机分配的token:{"easyedit_userid":用户id,"easyedit_loginip":"用户登录的ip","easyedit_last_time":"最后登录的时间"}}

    @classmethod
    def _____create_number(cls):
        res=''
        for i in range(6):
          res=res+ str(random.randrange(0, 100000)).zfill(5)
        return res
    @classmethod
    def _set_login_info(cls,easyedit_token,easyedit_userid,easyedit_loginip):
        cls.now_user_login_info1[easyedit_userid]=easyedit_token
        cls.now_user_login_info2[easyedit_token]={"easyedit_userid":easyedit_userid,"easyedit_loginip":easyedit_loginip,"easyedit_last_time":time.time()}
    #保存用户登录信息 用户id和登录ip
    @classmethod
    def set_login_info(cls,easyedit_userid,easyedit_loginip):
        new_time=time.time()
        while 1:
            easyedit_token=cls._____create_number()
            #这个随机num是否被使用
            if easyedit_token in cls.now_user_login_info2:
                #已被使用 检查最后登录时间是否超过30天
                if (cls.now_user_login_info2[easyedit_token]['easyedit_last_time']+cls.login_timeout<new_time):
                    #最后登录时间超过30天 覆盖旧的用户登录数据
                    cls._set_login_info(easyedit_token,easyedit_userid,easyedit_loginip)
                    #退出循环
                    return {"easyedit_token":easyedit_token}
                else:
                    #没超过30天 重新循环
                    continue
            else:
                #未被使用 使用该num 创建用户登录数据
                cls._set_login_info(easyedit_token,easyedit_userid,easyedit_loginip)
                #退出循环
                return {"easyedit_token":easyedit_token}
    #检查用户登录数据是否正确且登录时间未过期 正确则刷新时间
    @classmethod
    def check_user_login_data(cls,easyedit_userid,easyedit_token,easyedit_loginip):
        new_time=time.time()
        login_data=cls.now_user_login_info2.get(easyedit_token)
        if login_data is not None:
            #登录时间过期
            if login_data.get("easyedit_last_time")+cls.login_timeout<new_time:
                return False,{"type":"error","error_code":1,"message":"登录时间过期"}
            elif (login_data.get("easyedit_userid")==int(easyedit_userid)) and (login_data.get("easyedit_loginip")==easyedit_loginip):
                return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}
        return False,{"type":"error","error_code":1,"message":"验证不通过"}
    #数据库初始化
    @classmethod
    def db_init(cls):#
        config={'user_db':{
                    'id':{
                                        '名称':'id',
                                        '备注':'id',
                                        '主键':True, 
                                        '自增长':True,
                                        '索引':False,
                                        '字段类型':'INTEGER',
                                        '字段长度':None,
                                        },
                    'username':{
                                        '名称':'用户名',
                                        '备注':'用户名',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'VARCHAR',
                                        '字段长度':[0,10],
                                        },
                    'passwd':{
                                        '名称':'用户密码',
                                        '备注':'用户密码',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':None,
                                        '字段类型':'VARCHAR',
                                        '字段长度':[0,10],
                                        },
                        'name':{
                                            '名称':'用户昵称',
                                            '备注':'用户昵称',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,10],
                                            },
                }}
        #取出来color_db的数据
        cls.db_obj=base_db(db_data=config,db_dir_path=base_config['user_db_file'])
        # __test__post()#测试post 的功能 #增
        # __test__delete()#测试post 的功能 #删
        # __test__put()#测试post 的功能 #改
        #如果数据库不存在 那么创建
        condition_field=[["username",'test1'],["passwd",'test1']]
        # try:
        #     cls.db_obj.post(info={"id":0,'username':'test0','passwd':'test0',"name":"陆一"})
        # except:
        #     pass
        if cls.db_obj.get(select_field=['id'],condition_field=condition_field)['count']==0:
            cls.db_obj.post(info={'username':'test1','passwd':'test1',"name":"张三"})
            cls.db_obj.post(info={'username':'test2','passwd':'test2',"name":"李四"})
            cls.db_obj.post(info={'username':'test3','passwd':'test3',"name":"王五"})
            
    #验证用户信息 
    @classmethod
    def check_user(cls,username,passwd):
        if cls.db_obj is None:cls.db_init()
        try:
            condition_field=[["username",'test1'],["passwd",'test1']]
            tst=cls.db_obj.get(select_field=['id'],condition_field=condition_field)
            # print("test",condition_field,tst) 
            new_condition_field=[['username',username],['passwd',passwd]]
            res=cls.db_obj.get(select_field=['id'],condition_field=new_condition_field)
            # print("prin",new_condition_field,res)
            # print("res",res)
            if res['count']==1:
                
                return res['data'][0]['id']
        except:
            return False
#用户组件数据库_组件目录
class user_template_dir():
    
    #数据库初始化
    @classmethod
    def db_init(cls):#
        config={'temp_dir':{
                    'id':{
                                        '名称':'id',
                                        '备注':'id',
                                        '主键':True, 
                                        '自增长':True,
                                        '索引':False,
                                        '字段类型':'INTEGER',
                                        '字段长度':None,
                                        },
                    'name':{
                                        '名称':'一级组件库目录名称',
                                        '备注':'一级组件库目录名称',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'VARCHAR',
                                        '字段长度':[0,10],
                                        },
                    'user_id':{
                                        '名称':'作者id',
                                        '备注':'作者id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'VARCHAR',
                                        '字段长度':[0,10],
                                        },
                    'dir_id':{
                                            '名称':'目录id',
                                            '备注':'目录id',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,10],
                                            },
                    'use_num':{
                                            '名称':'该组件被多少个项目所使用',
                                            '备注':'该组件被多少个项目所使用',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'INTEGER',
                                            '字段长度':None,

                    },
                    'public_flag':{
                                            '名称':'是否公开此组件库,使得所有用户可以使用',
                                            '备注':'0表示公开,1表示可以通过私有编号使用,2表示只能自己使用',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'INTEGER',
                                            '字段长度':None,

                    },
                    'private_num':{
                        
                                            '名称':'私有编号', 
                                            '备注':'可以通过私有编号搜索到该组件 从而进行使用',
                                            '主键':False, 
                                            '自增长':False,
                                            '唯一索引':True,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,32],
                    },
                    'level':{
                        
                                            '名称':'组件版本', 
                                            '备注':'组件版本,表示该组件拥有多少个版本',
                                            '主键':False, 
                                            '自增长':False,
                                            '唯一索引':False,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,32],
                    }
                }}
        #取出来color_db的数据
        cls.db_obj=base_db(db_data=config,db_dir_path=base_config['db_dir'])
    
            
    @classmethod
    def _____create_number(cls):
        res=''
        for i in range(6):
          res=res+ str(random.randrange(0, 100000)).zfill(5)
        return res
    #新建 组件目录
    @classmethod
    def new_val(cls,name,user_id,dir_id,public_flag):
        # new_val(name,user_id,dir_id,public_flag)
        set_val={"name":name,"user_id":user_id,"dir_id":dir_id,"use_num":0,"public_flag":public_flag,"private_num":0}
        while True:
            try:
                set_val['private_num']=cls._____create_number()

                res=cls.db_obj.post(info=set_val)
                print(res)
                return {'type':"ok"}
            except:
                pass
    #修改目录名
    @classmethod
    def change_name(cls,user_id,dir1_id,name) :
        while True:
            try:
                res=cls.db_obj.put(
                    select_field=[['user_id',user_id],['dir1_id',dir1_id]],
                                   put_field_dct={"name":name})
                return {'type':"ok"}
            except:
                pass

    #设置目录1属性  - 公开 、需要邀请码、私有
    @classmethod
    def set_my_temp_dir1(cls,user_id,dir1_id,public_flag) :
        while True:
            try:
                res=cls.db_obj.put(
                    select_field=[['user_id',user_id],['dir1_id',dir1_id]],
                                   put_field_dct={"public_flag":public_flag})
                return {'type':"ok"}
            except:
                pass
    #重置目录1邀请码
    def set_my_temp_dir1_num(cls,user_id,dir1_id):
        while True:
            try:
                private_num=cls._____create_number()

                cls.db_obj.put(select_field=[['user_id',user_id],['dir1_id',dir1_id]],
                               put_field_dct={"private_num":private_num})
                return {'type':"ok","private_num":private_num}
            except:
                pass
    #查询指定用户的目录数据
    @classmethod
    def get_all_dir1(cls,user_id):
        
                    # 'id#id
                    # 'name# 一级组件库目录名称
                    # 'user_id #作者id',
                    # 'dir_id #目录id'
                    # 'use_num #该组件被多少个项目所使用',
                    #'public_flag #0表示公开,1表示可以通过私有编号使用,2表示只能自己使用',
                    #'private_num'#'私有编号'
                    #level 组件版本
        select_field=['id','name','user_id','dir_id','use_num','public_flag','private_num','level']
        new_condition_field=[['user_id',user_id]]
        try:
            res=cls.db_obj.get(select_field=select_field,condition_field=new_condition_field)
            # print("res:",res)
            if res['count']>=0:

                return res['data']
            
        except:
            return False
#用户组件数据库_组件
class user_template():
    
    #数据库初始化
    @classmethod
    def db_init(cls):# 
        config={'temp':{
                    'id':{
                                        '名称':'id',
                                        '备注':'id',
                                        '主键':True, 
                                        '自增长':True,
                                        '索引':False,
                                        '字段类型':'INTEGER',
                                        '字段长度':None,
                                        },
                    'name':{
                                        '名称':'组件名称',
                                        '备注':'组件名称',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'VARCHAR',
                                        '字段长度':[0,10],
                                        },
                    'user_id':{
                                        '名称':'作者id',
                                        '备注':'作者id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':None,
                                        '字段类型':'VARCHAR',
                                        '字段长度':[0,10],
                                        },
                    'dir1_id':{
                                            '名称':'目录1id',
                                            '备注':'目录1id',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,10],
                                            },
                    'temp_id':{
                                            '名称':'组件id',
                                            '备注':'组件id',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,10],
                                            },
                                            
                    'dir2_id':{
                                            '名称':'目录2id',
                                            '备注':'目录21id',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,10],
                                            },
                    'use_num':{
                                            '名称':'该组件被多少个项目所使用',
                                            '备注':'该组件被多少个项目所使用',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'INTEGER',
                                            '字段长度':None,

                    },
                    'public_flag':{
                                            '名称':'是否公开此组件库,使得所有用户可以使用',
                                            '备注':'0表示公开,1表示可以通过私有编号使用,2表示只能自己使用',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'INTEGER',
                                            '字段长度':None,

                    },
                    'private_num':{
                        
                                            '名称':'私有编号', 
                                            '备注':'可以通过私有编号搜索到该组件 从而进行使用',
                                            '主键':False, 
                                            '自增长':False,
                                            '唯一索引':True,
                                            '字段类型':'VARCHAR',
                                            '字段长度':[0,32],
                    },
                    'level':{
                        
                                            '名称':'组件版本', 
                                            '备注':'组件版本,表示该组件拥有多少个版本',
                                            '主键':False, 
                                            '自增长':False,
                                            '唯一索引':False,
                                            '字段类型':'INTEGER',
                                            '字段长度':[0,32],
                    }
                }}
        #取出来color_db的数据
        cls.db_obj=base_db(db_data=config,db_dir_path=base_config['db_dir'])
    
            
    @classmethod
    def _____create_number(cls):
        res=''
        for i in range(6):
          res=res+ str(random.randrange(0, 100000)).zfill(5)
        return res
    #新建 组件目录
    @classmethod 
    def new_val(cls,name,user_id,dir1_id,dir2_id,temp_id,public_flag):
        set_val={"temp_id":temp_id,"name":name,"user_id":user_id,"dir1_id":dir1_id,"dir2_id":dir2_id,"use_num":0,"public_flag":public_flag,"private_num":0,"level":0}
        while True:
            try:
                set_val['private_num']=cls._____create_number()

                cls.db_obj.post(info=set_val)
                return {'type':"ok","name":name,"dir1_id":dir1_id,"dir2_id":dir2_id,"use_num":0,"public_flag":public_flag,"private_num":0}
            except:
                pass
    #修改目录名
    @classmethod
    def change_name(cls,user_id,dir1_id,name) :
        while True:
            try:
                res=cls.db_obj.put(
                    select_field=[['user_id',user_id],['dir1_id',dir1_id]],
                                   put_field_dct={"name":name})
                return {'type':"ok"}
            except:
                pass

    #设置目录1属性  - 公开 、需要邀请码、私有
    @classmethod
    def set_my_temp_dir1(cls,user_id,dir1_id,public_flag) :
        while True:
            try:
                res=cls.db_obj.put(
                    select_field=[['user_id',user_id],['dir1_id',dir1_id]],
                                   put_field_dct={"public_flag":public_flag})
                return {'type':"ok"}
            except:
                pass
    #重置目录1邀请码
    def set_my_temp_dir1_num(cls,user_id,dir1_id):
        while True:
            try:
                private_num=cls._____create_number()

                cls.db_obj.put(select_field=[['user_id',user_id],['dir1_id',dir1_id]],
                               put_field_dct={"private_num":private_num})
                return {'type':"ok","private_num":private_num}
            except:
                pass
    #查询指定用户的目录数据
    @classmethod
    def get_all_temp(cls,user_id,dir1_id,dir2_id):
        
                    # 'id#id
                    # 'name# 一级组件库目录名称
                    # 'user_id #作者id',
                    # 'dir_id #目录id'
                    # 'use_num #该组件被多少个项目所使用',
                    #'public_flag #0表示公开,1表示可以通过私有编号使用,2表示只能自己使用',
                    #'private_num'#'私有编号'
                    #level 组件版本
        select_field=['id','name','user_id','dir1_id','dir2_id','use_num','public_flag','private_num','level',"temp_id"]
        new_condition_field=[['user_id',user_id],['dir1_id',dir1_id],['dir2_id',dir2_id]]
        try:
            res=cls.db_obj.get(select_field=select_field,condition_field=new_condition_field)
            if res['count']>=0:

                return res['data']
        except:
            return False

def is_valid_variable_name(name):  
    pattern = r'^[a-zA-Z_][a-zA-Z0-9_]*$'  
    return bool(re.match(pattern, name))  

def read_img(file_path):
    return cv2.imdecode(np.fromfile(file_path,dtype=np.uint8),-1)
# # 将URL编码为可打印形式
# url = 'http%3A%2F%2Fwww%2Eexample%2Ecom%2F%E4%B8%AD%E6%96%87%E6%9C%AC%E5%88%87'
# encoded_url = urllib.parse.quote(url)
# print(encoded_url)

# # 将编码后的URL解码回原始形式
# decoded_url = urllib.parse.unquote(encoded_url)
# print(decoded_url)
class base_class(tornado.web.RequestHandler):
    
    def _list_bytes2str(self,list_bytes):
        return list_bytes[0].decode('utf-8')
    def check_user(self):
        easyedit_userid = self.get_cookie("easyedit_userid")
        easyedit_token = self.get_cookie("easyedit_token")
        easyedit_loginip=self.get_ip()#获取登录时的ip
        return user_db.check_user_login_data(easyedit_userid,easyedit_token,easyedit_loginip)
    def check_user2(self):
        easyedit_userid = self.get_cookie("easyedit_userid")
        easyedit_token = self.get_cookie("easyedit_token")
        easyedit_loginip=self.get_ip()#获取登录时的ip
        try:try_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'
        except:return False,{"type":"error","error_code":1,"message":"没有登录"}
        try:os.makedirs(try_path)
        except:pass
        try_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'
        try:os.makedirs(try_path)
        except:pass
        try_path=base_config['temp_dir']+os.sep+easyedit_userid
        try:os.makedirs(try_path)
        except:pass
        return user_db.check_user_login_data(easyedit_userid,easyedit_token,easyedit_loginip)

            
    def get_ip(self):
        ip = self.request.headers.get("X-Forwarded-For")  
        if ip:  
            # 如果存在多个IP（由逗号分隔），通常取第一个  
            ip = ip.split(",")[0].strip()  
        else:  
            # 如果没有X-Forwarded-For头，则使用remote_ip  
            ip = self.request.remote_ip  
        return ip
    # #self.json_body自动转为dict
    def prepare(self):
        self.head_params=self.request.arguments
        try:
            self.json_body = self.body_params=self.request.body
            while not isinstance(self.json_body,dict):
                self.json_body =json.loads(self.json_body)
        except ValueError:
            self.json_body = {'error':'不是json格式'}
        login_flag,user_info=self.check_user2()#验证登录
        if login_flag is False:
            self.set_header("Content-Type", "application/json")  
            response = {"type":"error","message": "验证失败"}  
            self.finish(json.dumps(response))  
            return
        self.user_id=user_info['user_id']
        
    def get(self):
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        # 处理请求并返回响应
        self.write('get')
    def post(self):
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        self.json_body#获取请求的正文（body）数据 json格式
        # 处理请求并返回响应
        self.write('post')
    def put(self):
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        self.json_body#获取请求的正文（body）数据 json格式
        # 处理请求并返回响应
        self.write('put')
    def delete(self):
        # 获取请求参数
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        self.json_body#获取请求的正文（body）数据 json格式
        # 处理请求并返回响应
        self.write('delete')
class login_in(tornado.web.RequestHandler):
    def check_user(self):
        easyedit_userid = self.get_cookie("easyedit_userid")
        easyedit_token = self.get_cookie("easyedit_token")
        easyedit_loginip=self.get_ip()#获取登录时的ip
        return user_db.check_user_login_data(easyedit_userid,easyedit_token,easyedit_loginip)
    def check_user2(self):
        easyedit_userid = self.get_cookie("easyedit_userid")
        easyedit_token = self.get_cookie("easyedit_token")
        easyedit_loginip=self.get_ip()#获取登录时的ip
        try:try_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'
        except:return False,{"type":"error","error_code":1,"message":"没有登录"}
        try:os.makedirs(try_path)
        except:pass
        try_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'
        try:os.makedirs(try_path)
        except:pass
        try_path=base_config['temp_dir']+os.sep+easyedit_userid
        try:os.makedirs(try_path)
        except:pass
        return user_db.check_user_login_data(easyedit_userid,easyedit_token,easyedit_loginip)

            
    def get_ip(self):
        ip = self.request.headers.get("X-Forwarded-For")  
        if ip:  
            # 如果存在多个IP（由逗号分隔），通常取第一个  
            ip = ip.split(",")[0].strip()  
        else:  
            # 如果没有X-Forwarded-For头，则使用remote_ip  
            ip = self.request.remote_ip  
        return ip
    # #self.json_body自动转为dict
    def prepare(self):
        self.head_params=self.request.arguments
        try:
            self.json_body = self.body_params=self.request.body
            while not isinstance(self.json_body,dict):
                self.json_body =json.loads(self.json_body)
        except ValueError:
            self.json_body = {'error':'不是json格式'}
        
    def get(self):
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        # 处理请求并返回响应
        self.write('get')
    def post(self):
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        self.json_body#获取请求的正文（body）数据 json格式
        # 处理请求并返回响应
        self.write('post')
    def put(self):
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        self.json_body#获取请求的正文（body）数据 json格式
        # 处理请求并返回响应
        self.write('put')
    def delete(self):
        # 获取请求参数
        self.request.arguments#可以通过self.request.arguments获取请求中的数据
        self.json_body#获取请求的正文（body）数据 json格式
        # 处理请求并返回响应
        self.write('delete')
    def post(self):
        # self.request.arguments#可以通过self.request.arguments获取请求中的数据
        # self.json_body#获取请求的正文（body）数据 json格式
        try:
            #验证用户登录账号密码后 验证用户id
            easyedit_userid=user_db.check_user(self.json_body.get("username"),self.json_body.get("password"))
            if easyedit_userid not in [False,None]:
                easyedit_loginip=self.get_ip()#获取登录时的ip
                res_dct=user_db.set_login_info(easyedit_userid,easyedit_loginip)
                write_val={"type":"ok","easyedit_userid":easyedit_userid,"easyedit_token":res_dct['easyedit_token']}
            else:
                write_val={"type":"error","message":"验证不通过"}
        except Exception as s:
            write_val={"type":"error","message":"验证不通过"+str(s)}
        # print("write)val:",write_val)
        self.write(write_val)
#获取 我的项目目录
class get_project_info(base_class):      
    #获取 我的项目 文件夹列表
    def get_self_project_lst(self):
        res={}
        self_dir=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'
        for dir_id in os.listdir(self_dir):
            dir_path=self_dir+os.sep+dir_id
            if not os.path.isdir(dir_path):continue
            # print(self_dir+os.sep+"config.yaml")
            with open(dir_path+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            res[dir_id]={
                "base_info": {
                    "vue_name": "a_1_0_2_15_1",
                    "deepcopy_data": config__
                },
                "dict": {}
            }
        return res
    def post(self):
        self_info=self.get_self_project_lst()#我的项目目录
        self.write({"type":"okk","data":self_info})
# 修改我的目录名称
class change_project_dir1(base_class):
    def change_project_dir1(self,dir1_id,name):
        
        res={}
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+dir1_id
        config_path=dir_path+os.sep+'config.yaml'
        with open(config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        config__['name']=name
        
        with open(config_path, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
            res[dir1_id]={
                "base_info": {
                    "deepcopy_data": config__
                },
            }
        return res
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        res=self.change_project_dir1(dir1_id,name)
        self.write({"type":"okk","data":res})
class del_pro_dir1(base_class):
    def del_dir(self,dir1_id):
        
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+dir1_id
        dir_lst=os.listdir(dir_path+os.sep+'projects')
        if len(dir_lst):
            return {"type":"error","message":"无法删除目录[未删除项目:%s个]"%len(dir_lst)}
        try:
            shutil.rmtree(dir_path)
        except Exception as e:
            return {"type":"error","message":"删除出现异常%s"%e}
        return {"type":"ok","message":"删除成功","data":{"dir1_id":dir1_id}}
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        res=self.del_dir(dir1_id)
        self.write(res)
class get_pro_editor(base_class):
    def get_pro_editor(self,dir1_id):
        
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+dir1_id
        dir_lst=os.listdir(dir_path+os.sep+'projects')
        if len(dir_lst):
            return {"type":"error","message":"无法删除目录[未删除项目:%s个]"%len(dir_lst)}
        try:
            shutil.rmtree(dir_path)
        except Exception as e:
            return {"type":"error","message":"删除出现异常%s"%e}
        return {"type":"ok","message":"删除成功","data":{"dir1_id":dir1_id}}
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        
        pro_id=self.json_body.get("pro_id")
        res=self.get_pro_editor(dir1_id,pro_id)
        self.write(res)

with open(pro+os.sep+os.sep+'_static_dir'+os.sep+'python.png', 'rb') as f:  
    no_img = f.read()  
class change_pro_img(base_class):
    def post(self):
        file_info = self.request.files['file'][0]  
        file_name = file_info['filename']  
        file_body = file_info['body']  
  
        # 获取额外的参数  
        dir1_id = str(self.get_argument('dir1_id')  )  
        user_id = str(self.get_argument('user_id')  )  
        num = str(self.get_argument('num')  )  
        if(user_id!=self.user_id):
            self.write({"type":"error","message":"没有权限修改图片"})
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+dir1_id+os.sep+'projects'+os.sep+num
        img_path=os.path.join(dir_path,'main.png')
        with open(img_path, 'wb') as f:  
            f.write(file_body)  
        self.write({"type":"ok","message":"修改成功","num":num})
class get_pro_img(base_class):
    def get(self,x):
        dir1_id=str(self.head_params.get("dir1_id")[0])[2:-1]
        user_id=str(self.head_params.get("user_id")[0])[2:-1]
        num=str(self.head_params.get("num")[0])[2:-1]
        dir_path=base_config['user_dir']+os.sep+user_id+os.sep+'self'+os.sep+dir1_id+os.sep+'projects'+os.sep+num
        img_path=os.path.join(dir_path,'main.png')
        print("img_path:",img_path)
        # 检查文件是否存在  
        if not os.path.exists(img_path):  
            image_data= no_img
        else:
            # 读取图片文件  
            with open(img_path, 'rb') as f:  
                image_data = f.read()  
          
        # 设置响应头  
        self.set_header('Content-Type', 'image/jpeg')  # 根据你的图片类型设置，这里是 JPEG  
        self.set_header('Content-Length', len(image_data))  
          
        # 写入响应体  
        self.write(image_data) 
#获取 他人目录
class get_project_info2(base_class):      
    #获取 我的项目 文件夹列表
    #res:[{"num":1,"name":"项目名1"},{"num":2,"name":"项目名2"}]
    #获取 他人项目 列表
    #res:[{"id":1,"name":"用户名2"},{"id":2,"name":"用户名2"}]
    def get_other_lst(self):
        res={}
        other_dir=base_config['user_dir']+os.sep+self.user_id+os.sep+'other'
        if not os.path.isdir(other_dir):
            try:os.makedirs(other_dir)
            except:pass
        print("什么鬼")
        print("other_dir",other_dir,os.listdir(other_dir))
        res2=user_db.db_obj.get(select_field=['id',"name"],condition_field={"id":[int(item) for item in os.listdir(other_dir)]})
        res2=res2['data']
        for iiitem in res2:
            res[iiitem['id']]={
                
                "base_info": {
                    "vue_name": "a_1_0_2_16_1",
                    "deepcopy_data": {"name":iiitem['name']}
                },
                "dict": {}
            }
        return res 
    def post(self):
        other_info=self.get_other_lst()#他人目录
        self.write({"type":"okk","data":other_info})

#获取 他人项目 的所有项目目录
class get_other_project_dir(base_class):    
    #获取我的项目 目录下的
    #获取他人项目的所有目录
    def get_other_project_dir(self,other_id):
        res=[]
        easyedit_userid = self.get_cookie("easyedit_userid")
        other_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'+os.sep+other_id
        for item in os.listdir(other_dir):
            other_project=base_config['user_dir']+os.sep+other_id+os.sep+'self'+os.sep+item
            with open(other_project+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            res.append({"num":int(item),'name':config__['name']})
        res.sort(key=lambda item: item["num"]) 
        return res
    def post(self):
        other_id=self.json_body.get("other_id")
        other_project_dir=self.get_other_project_dir(other_id)
        self.write({"other_project_dir":other_project_dir})
#获取我的项目XXX目录下的所有项目信息
class get_my_project_all(base_class):        
    #获取我的项目 XXX目录下的所有项目 信息
    #res [{'num':1,"name":xxx，"other_lst":[],"last_time":sdaf}]
    def get_my_project_all(self,dir1_id):
        res=[]
        self_dir=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+dir1_id+os.sep+"projects"
        print(self_dir)
        for project_id in os.listdir(self_dir):
            try:
                with open(self_dir+os.sep+project_id+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                    config__ = yaml.load(f, Loader=yaml.FullLoader)
            except:pass
            config__['num']=int(project_id)
            res.append(copy.copy(config__))
        res.sort(key=lambda item: item["num"]) 
        # print("fdadf",res)
        return {"project_all":res}
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        res=self.get_my_project_all(dir1_id)
        self.write(res)

#获取他人项目XXX目录下的所有项目信息
class get_other_project_all(base_class):   
    #获取他人项目project_id目录下的所有项目信息
    #res [{'num':1,"name":xxx}]
    def get_other_project_all(self,other_id,project_dir):
        res=[]
        other_dir=base_config['user_dir']+os.sep+self.user_id+os.sep+'other'+os.sep+other_id+os.sep+project_dir+os.sep+"projects"
        for project_id in os.listdir(other_dir):
            other_project=base_config['user_dir']+os.sep+other_id+os.sep+'self'+os.sep+project_dir+os.sep+"projects"+os.sep+project_id
            with open(other_project+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            config__['num']=int(project_id)
            res.append(copy.copy(config__))
        res.sort(key=lambda item: item["num"]) 
        return {"project_all":res}
     
    def post(self):
        other_id=self.json_body.get("other_id")
        project_dir=self.json_body.get("dir1_id")
        res=self.get_other_project_all(other_id,project_dir)
        self.write(res)
#获取他人项目 某#获取 他人项目 列表
class get_other_projects(base_class):    
    #获取他人项目 某#获取 他人项目 列表
    def get_other_projects(self,other_id):
        res=[]
        other_dir=base_config['user_dir']+os.sep+self.user_id+os.sep+'other'+os.sep+other_id
        if not os.path.isdir(other_dir):
            try:os.makedirs(other_dir)
            except:pass
        for item in os.listdir(other_dir):
            other_project=base_config['user_dir']+os.sep+other_id+os.sep+'self'+os.sep+item
            with open(other_project+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            res.append({"num":int(item),'name':config__['name']})
        res.sort(key=lambda item: item["num"]) 
        res_dict={}
        for item2 in res:
            res_dict[item2["num"]]={
                
                "base_info": {
                    "vue_name": "a_1_0_2_17_1",
                    "deepcopy_data": {"name":item2['name']}
                },
                "dict": {}
            }
        return res_dict
# {"type": "okk", "data": [{"num": 1, "name": "1"}]}
    def post(self):
        other_id=self.json_body.get("other_id")
        res=self.get_other_projects(other_id)
        self.write({"type":"okk","data":res})
#新建项目目录
class create_project_dir(base_class):    
#新建项目目录
    def create_project_dir(self,name):
        #获取我的项目配置文件
        main_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'
        if not os.path.isdir(main_path):
            try:os.makedirs(main_path)
            except:pass
        main_yaml=main_path+os.sep+'main.yaml'
        if not os.path.exists(main_yaml):
            with open(main_yaml, 'w') as file:  
                yaml.dump({"index":0}, file, default_flow_style=False, sort_keys=False)  
        
        with open(main_yaml, 'r',encoding='utf-8') as f:
            data = yaml.load(f, Loader=yaml.FullLoader)
        data['index']=data['index']+1
        with open(main_yaml, 'w') as file:  
            yaml.dump(data, file, default_flow_style=False, sort_keys=False)  
        dir_id=str(data['index'])
        create_dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+dir_id
        os.makedirs(create_dir_path+os.sep+"projects")
        create_config_file=create_dir_path+os.sep+"config.yaml"
        with open(create_config_file, 'w') as file:  
            yaml.dump({"name":name}, file, default_flow_style=False, sort_keys=False)  
        return {dir_id:{
            "base_info": {
                "vue_name": "a_1_0_2_15_1",
                "deepcopy_data": {"name":name}
            },
            "dict": {}
        }}
    def post(self):
        name=self.json_body.get("name")
        res=self.create_project_dir(name)
        self.write({"type":"okk","data":res})
#删除我的项目目录
class del_project_dir(base_class):      
    #删除我的项目目录
    def del_project_dir(self,project_dir):
        easyedit_userid = self.get_cookie("easyedit_userid")
        del_dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)
        for project_id in os.listdir(del_dir_path):
            project_config_path=del_dir_path+os.sep+project_id+os.sep+"config.yaml"
            with open(project_config_path, 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            other_lst=config__.get("other_lst")
            #删除所有参与项目的人 的数据
            if other_lst is not None:
                for other_id in other_lst:
                    other_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'+os.sep+other_id
                    try:shutil.rmtree(other_dir+os.sep+"projects"+os.sep+project_id)    
                    except:pass
                    if len(os.listdir(other_dir+os.sep+"projects"))==0:
                        try:shutil.rmtree(other_dir)    
                        except:pass
        try:shutil.rmtree(del_dir_path)
        except:pass
        return {"type":"ok",'message':"删除成功"}
     
    def post(self):
        project_dir=self.json_body.get("project_dir")
        res=self.del_project_dir(project_dir)
        self.write(res)
#新建我的项目
class create_project(base_class):        
    def create_project(self,dir1_id,name):
        global 新项目初始内容
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+str(dir1_id)
        #获取新项目id
        yaml_path=dir_path+os.sep+"config.yaml"
        with open(yaml_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        config__['index']=config__.get("index",0)+1
        with open(yaml_path, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
        #创建项目目录
        pro_dir=dir_path+os.sep+'projects'+os.sep+str(config__['index'])
        try:os.makedirs(pro_dir)
        except:pass
        #创建项目配置文件
        create_config_file=pro_dir+os.sep+"config.yaml"
        yaml_val={"name":name,"other_lst":[],"last_time":time.time()}
        with open(create_config_file, 'w') as file:  
            yaml.dump(yaml_val, file, default_flow_style=False, sort_keys=False)  
        #创建项目的db文件夹
        db_dir=pro_dir+os.sep+"db_dir"
        try:os.makedirs(db_dir)
        except:pass
        #项目初始数据
        新项目初始内容["project_name"]=name
        新项目初始内容["project_id"]=f"{self.user_id}_{dir1_id}_{config__['index']}"
        main_yaml_val=新项目初始内容
        #项目初始数据存放的 yaml
        config_yaml=pro_dir+os.sep+"main.yaml"
        with open(config_yaml, 'w') as file:  
            yaml.dump(main_yaml_val, file, default_flow_style=False, sort_keys=False)  
        yaml_val['num']=config__['index']
        return yaml_val
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        res=self.create_project(dir1_id,name)
        self.write({"type":"ok","data":res})
#保存项目
class save_project(base_class):    
    #保存项目
    def save_project(self,user_id,project_dir,project_id):
        global config_dct_data_
        # print(config_dct_data_)
        create_dir_path=base_config['user_dir']+os.sep+user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+str(project_id)
        
        config_yaml=create_dir_path+os.sep+"main.yaml"#项目初始数据存放的 yaml
        with open(config_yaml, 'w') as file:  
            yaml.dump(config_dct_data_[(user_id,project_dir,project_id)]['info'], file, default_flow_style=False, sort_keys=False)  
        print("保存成功")
        return {"type":"ok",'message':"保存成功"}
    def post(self):
        print("开始保存...")
        user_id=self.json_body.get("user_id")
        project_dir=self.json_body.get("project_dir")
        project_id=self.json_body.get("project_id")
        #todo 验证项目权限
        res=self.save_project(user_id,project_dir,project_id)
        self.write(res)
#删除我的项目
class del_project(base_class):        
    #删除我的项目
    def del_project(self,project_dir,project_id):
        del_dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=del_dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        #删除所有参与项目的人 的数据
        if other_lst is not None:
            for other_id in other_lst:
                other_dir=base_config['user_dir']+os.sep+str(other_id)+os.sep+'other'+os.sep+self.user_id+os.sep+str(project_dir)
                try:shutil.rmtree(other_dir+os.sep+"projects"+os.sep+project_id)    
                except:pass
                if len(os.listdir(other_dir+os.sep+"projects"))==0:
                    try:shutil.rmtree(other_dir)    
                    except:pass
                d2=base_config['user_dir']+os.sep+str(other_id)+os.sep+'other'+os.sep+self.user_id
                if len(os.listdir(d2))==0:
                    try:shutil.rmtree(d2)    
                    except:pass
        try:shutil.rmtree(del_dir_path)
        except:pass
        return {"type":"ok",'message':"删除成功","num":project_id,"dir1_id":project_dir,"user_id":self.user_id}
    
    def post(self):
        dir1_id=str(self.json_body.get("dir1_id"))
        user_id=str(self.json_body.get("user_id"))
        num=str(self.json_body.get("num"))
        if(user_id!=self.user_id):
            self.write({"type":"error","message":"不能使用此接口删除别人的项目"})
            return
        res=self.del_project(dir1_id,num)
        self.write(res)
#修改我的项目名称
class change_project(base_class):    
    #修改项目名称
    def change_project(self,project_dir,project_id,project_name):
        easyedit_userid = self.get_cookie("easyedit_userid")
        dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+str(project_id)
        config_file=dir_path+os.sep+"config.yaml"
        yaml_val={"name":project_name,"other_lst":[],"last_time":time.time()}
        
        with open(config_file, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
            config__['name']=project_name
        with open(config_file, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
        return {"type":"ok","message":"修改成功","name":project_name,"num":project_id}

    def post(self):
        {"dir1_id":"22","user_id":"1","num":7,"name":"qqq"}
        project_dir=self.json_body.get("dir1_id")
        user_id=self.json_body.get("user_id")
        if(user_id!=self.user_id):
            self.write({"type":"error","message":"不能使用此接口修改别人的项目"})
            return
        project_id=self.json_body.get("num")
        project_name=self.json_body.get("name")
        res=self.change_project(project_dir,project_id,project_name)
        self.write(res)
#查看项目参与者目录
class project_user(base_class):        
    #查看项目参与者目录
    def project_user(self,project_dir,project_id):
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        res=user_db.db_obj.get(select_field=['id',"name"],condition_field={"id":[int(item) for item in other_lst]})
        res=res['data']
        res.sort(key=lambda item: item["id"]) 
        # print("...res:",res,other_lst)
        return {"project_user":res}

    def post(self):
        dir1_id=str(self.json_body.get("dir1_id"))
        num=str(self.json_body.get("num"))
        user_id=str(self.json_body.get("user_id"))
        if user_id!=self.user_id:
            self.write({"type":"error","message":"不是自己的项目 无权限查看"})
            return

        res=self.project_user(dir1_id,num)
        self.write(res)
#添加别人参与我的项目
class add_other_project(base_class):    
    #添加别人参与我的项目
    def add_other_project(self,project_dir,project_id,other_id):
        try:
            other_dct=user_db.db_obj.get(select_field=['id',"name"],condition_field={"id":[int(item) for item in [other_id]]})['data'][0]
        except:
            return {"type":"error","message":"不存在这个用户"}
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        if other_id not in other_lst:
            other_lst.append(other_id)
        else:
            return {"type":"error","message":"已添加这个用户"}

        config__['other_lst']=other_lst
        with open(project_config_path, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
        #别人的项目文件夹
        
        dir_path=base_config['user_dir']+os.sep+other_id+os.sep+'other'+os.sep+self.user_id+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        try:os.makedirs(dir_path)
        except:pass
        return {"type":"ok","data":{"user_id":other_id,"name":other_dct['name']}}
    def post(self):
        dir1_id=str(self.json_body.get("dir1_id"))
        num=str(self.json_body.get("num"))
        user_id=str(self.json_body.get("user_id"))
        other_id=str(self.json_body.get("other_id"))
        if user_id!=self.user_id:
            self.write({"type":"error","message":"不是自己的项目 无权限"})
            return
        if other_id==self.user_id:
            self.write({"type":"error","message":"不能添加自己"})
            return
        res=self.add_other_project(dir1_id,num,other_id)

        self.write(res)
#删除别人参与我的项目
class del_other_project(base_class):     
     #删除别人参与我的项目
    def del_other_project(self,project_dir,project_id,other_id,del_idx):
        dir_path=base_config['user_dir']+os.sep+self.user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        try:other_lst.remove(other_id)
        except:pass
        config__['other_lst']=other_lst
        with open(project_config_path, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
        return {"type":"ok",'message':"成功","del_idx":del_idx}
      
    def post(self):
        project_dir=str(self.json_body.get("dir1_id"))
        user_id=str(self.json_body.get("user_id"))
        if user_id!=self.user_id:
            self.write({"type":"error","message":"不是自己的项目 无权限"})
            return
        other_id=str(self.json_body.get("other_id"))
        project_id=str(self.json_body.get("num"))
        del_idx=str(self.json_body.get("del_idx"))
        
        res=self.del_other_project(project_dir,project_id,other_id,del_idx)
        self.write(res)
#运行流程
class run_flow(base_class):   
    #运行项目的指定流程
    def run_flow(self,user_id,project_dir,project_id,flow_id):
        global config_dct_data_
        all_data=config_dct_data_[(user_id,project_dir,project_id)]['info']#完整的项目数据
        project_path=(user_id,project_dir,project_id,flow_id)#用户1的目录1的项目1的流程1
        if self.json_body.get("type")=="run_flow":
            print("运行")
            send_message=flow_eee(all_data,flow_id,project_path).start_flow()
        elif self.json_body.get("type")=="stop_flow":
            print("结束")
            send_message=flow_eee(all_data,flow_id,project_path).stop_flow()
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        return {"type":"ok"} 
    def post(self):
        user_id=self.json_body.get("user_id")
        project_dir=self.json_body.get("project_dir")
        project_id=self.json_body.get("project_id") 
        flow_id=self.json_body.get("flow_id")
        res=self.run_flow(user_id,project_dir,project_id,flow_id)
        self.write(res)
from _base_tool.python.__输出数据库表定义 import base2
class db_create_info(base_class):
    def post(self):
        global config_dct_data_
        user_id=self.json_body.get("user_id")
        project_dir=self.json_body.get("project_dir")
        project_id=self.json_body.get("project_id") 
        db_id=self.json_body.get("db_id")
        all_data=config_dct_data_[(user_id,project_dir,project_id)]['info']#完整的项目数据
        db_data=all_data['db_config']['dict']['1']['dict'][str(db_id)]
        obj=base2(db_data=db_data)
        if isinstance(obj.table__info,tuple):
            self.write({"type":"error","message":obj.table__info[1]})
        else:
            self.write({"type":"okk","message":obj.table__info})
        # except:
        #     self.write({"type":"okk","message":obj.table__info})


#结束流程
class stop_flow(base_class):  
    #停止项目的指定流程
    def stop_flow(self,user_id,project_dir,project_id,flow_id):
        global config_dct_data_
        all_data=config_dct_data_[(user_id,project_dir,project_id)]['info']#完整的项目数据
        project_path=(user_id,project_dir,project_id,flow_id)#用户1的目录1的项目1的流程1
        key=(user_id,project_dir,project_id)
        send_message=flow_eee(all_data,flow_id,project_path).stop_flow()
        将更新下发到所有用户(key,send_message)
        return {"type":"ok"}  
    def post(self):
        user_id=self.json_body.get("user_id")
        project_dir=self.json_body.get("project_dir") 
        project_id=self.json_body.get("project_id") 
        flow_id=self.json_body.get("flow_id")
        res=self.stop_flow(user_id,project_dir,project_id,flow_id)
        self.write(res)

class template_all(base_class):
    def _list_bytes2str(self,list_bytes):
        return list_bytes[0].decode('utf-8')
    #获取所有目录1
    def get_all_dir1(self,user_id):
        res=user_template_dir.get_all_dir1(user_id) 
        #"dir1_id":dir_id,"name":name,"public_flag":public_flag,"use_num":0
        return {"type":"ok","data":res}
        
    #新增目录1
    def add_my_temp_dir1(self,user_id,name,public_flag):
        #用户id->组件目录1->组件目录2->组件->组件版本0
        user_dir=base_config['temp_dir']+os.sep+user_id
        try:dir_id=str(len(os.listdir(user_dir))+1)
        except:dir_id='0'
        create_dir=os.path.join(user_dir,dir_id)
        try:os.makedirs(create_dir)
        except:pass
        user_template_dir.new_val(name,user_id,dir_id,public_flag)
        return {"type":"success",'message':"新增成功","dir1_id":dir_id,"name":name,"public_flag":public_flag,"use_num":0}
    #修改目录1的名称
    def change_my_temp_dir1_name(self,user_id,dir1_id,name):
        return user_template_dir.change_name(user_id,dir1_id,name) 
    #获取目录1的数据
    def get_my_temp_dir1(self,user_id,dir1_id):
        #用户id->组件目录1->组件目录2->组件->组件版本0
        user_dir=base_config['temp_dir']+os.sep+user_id+os.sep+dir1_id
        lst=os.listdir(user_dir)
        res=[]
        for item in lst:
            yaml_path=user_dir+os.sep+item+os.sep+'config.yaml'
            with open(yaml_path, 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            res.append({"name":config__['name'],"dir2_id":item})
        
        return {"type":"成功","data":res}
     #设置目录1属性  - 公开 、需要邀请码、私有
    def set_my_temp_dir1(self,user_id,dir1_id,public_flag):
        return user_template_dir.set_my_temp_dir1(user_id,dir1_id,public_flag) 
    #重置0
    def set_my_temp_dir1_num(self,user_id,dir1_id):
        return user_template_dir.set_my_temp_dir1_num(user_id,dir1_id) 
    #更改目录1的显示图标
    def change_my_temp_dir1_img(self,user_id,dir1_id,img):
        pass
    #新增目录2
    def add_my_temp_dir2(self,user_id,dir1_id,name):
        #用户id->组件目录1->组件目录2->组件->组件版本0
        dir1_path=base_config['temp_dir']+os.sep+user_id+os.sep+dir1_id
        try:dir2_id=str(len(os.listdir(dir1_path))+1)
        except:dir2_id='目录1邀请码'
        create_dir=os.path.join(dir1_path,dir2_id)
        os.makedirs(create_dir)
        with open(create_dir+os.sep+'config.yaml', 'w') as file:  
            yaml.dump({"name":name}, file, default_flow_style=False, sort_keys=False)  
        return {"type":"success","dir2_id":dir2_id,"name":name}
    #修改用户目录2的名称
    def change_temp_dir2_name(self,user_id,dir1_id,dir2_id,name):
        #用户id->组件目录1->组件目录2->组件->组件版本0
        dir2_path=base_config['temp_dir']+os.sep+user_id+os.sep+dir1_id+os.sep+dir2_id
        
        with open(dir2_path+os.sep+'config.yaml', 'w') as f:  
           config__ = yaml.load(f, Loader=yaml.FullLoader)
           config__['name']=name
           yaml.dump(config__, f, default_flow_style=False, sort_keys=False)  
        return {"type":"success","dir_id":dir2_id}
    
    #获取目录2的数据
    def get_my_temp_dir2(self,user_id,dir1_id,dir2_id):
        return {"type":"成功","data":user_template.get_all_temp(user_id,dir1_id,dir2_id)}
        
    #更改目录2的显示图标
    def change_temp_dir2_img(self,user_id,dir1_id,dir2_id,img):
        pass
    #添加组件
    def add_my_temp(self,user_id,dir1_id,dir2_id,name,public_flag,objs):
        #user_id 组件开发人的id
        #dir1_id 目录1的id
        #dir2_id 目录2的id
        #name 组件的名称
        # print(user_id,dir1_id,dir2_id,name,public_flag,objs)
        dir2_path=os.path.join(base_config["temp_dir"],user_id,dir1_id,dir2_id)
        temp_id=str(len(os.listdir(dir2_path))+1)
        temp_dir=os.path.join(dir2_path,temp_id,"temp",'1')
        try:os.makedirs(temp_dir)
        except:pass
            # 遍历所有上传的文件  
         
        for _name, file_info in objs:  
            for file_meta in file_info:  
                # 获取文件名（这里可能包含路径信息）  
                parts=os.path.split(file_meta['filename'] )
                body=file_meta['body']
                if len(parts) > 1:  
                    # 重建目录结构  
                    dir_path = os.path.join(temp_dir, *parts[:-1])  
                    if not os.path.exists(dir_path):  
                        os.makedirs(dir_path)  
                    # 更新文件名以只包含最后一部分  
                    filename = parts[-1]  

                # 计算文件的完整保存路径  
                file_path = os.path.join(temp_dir, filename)  

                # 写入文件  
                with open(file_path, 'wb') as f:  
                    f.write(body)
        res=user_template.new_val(name,user_id,dir1_id,dir2_id,temp_id,public_flag)
        return res
    #更新组件
    def update_my_temp(self,user_id,dir1_id,dir2_id,temp_id,obj):
        #user_id 组件开发人的id
        #dir1_id 目录1的id
        #dir2_id 目录2的id
        #temp_id 组件的id
        pass
    #修改组件名
    def change_my_temp_name(self,user_id,dir1_id,dir2_id,temp_id,name):
        #user_id 组件开发人的id
        #dir1_id 目录1的id
        #dir2_id 目录2的id
        #temp_id 组件的id
        #name 组件的名称
        pass
    #修改版本名
    def change_my_temp_level_name(self,user_id,dir1_id,dir2_id,temp_id,temp_level,name):
        #user_id 组件开发人的id
        #dir1_id 目录1的id
        #dir2_id 目录2的id
        #temp_id 组件的id
        #temp_level 组件的版本号
        #name 组件的版本号的名称
        pass
    #设置组件属性  - 公开 、需要邀请码、私有
    def set_my_temp(self,user_id,dir1_id,dir2_id,temp_id,public_flag):
        pass
    #重置组件邀请码
    def set_my_temp_num(self,user_id,dir1_id,dir2_id,temp_id):
        pass
    #更改组件的显示图标
    def change_temp_img(self,user_id,dir1_id,dir2_id,temp_id,img):
        pass
    def post(self):
        # print("开始验证登录")
        login_flag,user_info=self.check_user2()#验证登录
        post_type=self.request.arguments.get("type")
        
        if post_type is None:
            post_type=self.json_body.get("type")
        else:
            post_type=self._list_bytes2str(post_type)
        # print("请求类型:",post_type)
        if login_flag is True:
            print("验证通过")
            # print(self.request)  
             # 遍历所有上传的文件  
            
        else:
            print("验证失败",user_info)
        if login_flag is True:
            user_id=user_info['user_id']
            #验证登录成功
            #self.json_body#获取请求的正文（body）数据 json格式
            #获取所有目录1
            if post_type=="get_all_dir1":
                self.write(self.get_all_dir1(user_id))
            #新增目录1
            elif post_type=="add_my_temp_dir1":
                # print("处理内容:新增目录1")
                name=self.json_body.get("name")
                public_flag=self.json_body.get("public_flag")
                res=self.add_my_temp_dir1(user_id,name,public_flag)
                # print("新增目录1:",res)
                self.write(res)
            #修改目录1的名称
            elif post_type=="change_my_temp_dir1_name":
                
                name=self.json_body.get("name")
                dir1_id=self.json_body.get("dir1_id")
                res=self.change_my_temp_dir1_name(user_id,dir1_id,name)
                self.write({"change_my_temp_dir1_name":res})
            #设置目录1属性  - 公开 、需要邀请码、私有
            elif post_type=="set_my_temp_dir1":
                dir1_id=self.json_body.get("dir1_id")
                public_flag=self.json_body.get("public_flag")
                res=self.set_my_temp_dir1(user_id,dir1_id,public_flag)
                self.write({"set_my_temp_dir1":res})
            #获取目录1的数据
            elif post_type=="get_my_temp_dir1":
                dir1_id=self.json_body.get("dir1_id")
                res=self.get_my_temp_dir1(user_id,dir1_id)
                self.write(res)
            #重置目录1邀请码
            elif post_type=="set_my_temp_dir1_num":
                dir1_id=self.json_body.get("dir1_id")
                res=self.set_my_temp_dir1_num(user_id,dir1_id)
                self.write({"set_my_temp_dir1_num":res})
            #更改目录1的显示图标
            elif post_type=="change_my_temp_dir1_img":
                dir1_id=self.json_body.get("dir1_id")
                img=self.json_body.get("img")
                res=self.change_my_temp_dir1_img(user_id,dir1_id,img)
                self.write({"change_my_temp_dir1_img":res})
            #新增目录2
            elif post_type=="add_my_temp_dir2":
                dir1_id=self.json_body.get("dir1_id")
                name=self.json_body.get("name")
                res=self.add_my_temp_dir2(user_id,dir1_id,name)
                self.write(res)
            #修改用户目录2的名称
            elif post_type=="change_temp_dir2_name":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                name=self.json_body.get("name")
                res=self.change_temp_dir2_name(user_id,dir1_id,dir2_id,name)
                self.write({"change_temp_dir2_name":res})
            #获取目录2的数据
            elif post_type=="get_my_temp_dir2":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                res=self.get_my_temp_dir2(user_id,dir1_id,dir2_id)
                self.write(res)
            #更改目录2的显示图标
            elif post_type=="change_temp_dir2_img":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                img=self.json_body.get("img")
                res=self.change_temp_dir2_img(user_id,dir1_id,dir2_id,img)
                self.write({"change_temp_dir2_img":res})
            #添加组件
            elif post_type=="add_my_temp":
                # print("进入添加组件...")
                dir1_id=self._list_bytes2str(self.request.arguments.get("dir1_id"))
                dir2_id=self._list_bytes2str(self.request.arguments.get("dir2_id"))
                name=self._list_bytes2str(self.request.arguments.get("name")  )
                public_flag=self._list_bytes2str(self.request.arguments.get("public_flag"))
                objs=self.request.files.items()
                res=self.add_my_temp(user_id,dir1_id,dir2_id,name,public_flag,objs)
                self.write(res)
            #更新组件
            elif post_type=="update_my_temp":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                temp_id=self.json_body.get("temp_id")
                obj=self.json_body.get("obj")
                res=self.update_my_temp(user_id,dir1_id,dir2_id,temp_id,obj)
                self.write({"update_my_temp":res})
            #修改组件名
            elif post_type=="change_my_temp_name":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                temp_id=self.json_body.get("temp_id")
                name=self.json_body.get("name")
                res=self.change_my_temp_name(user_id,dir1_id,dir2_id,temp_id,name)
                self.write({"change_my_temp_name":res})
            #修改版本名
            elif post_type=="change_my_temp_level_name":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                temp_id=self.json_body.get("temp_id")
                temp_level=self.json_body.get("temp_level")
                name=self.json_body.get("name")
                res=self.change_my_temp_level_name(user_id,dir1_id,dir2_id,temp_id,temp_level,name)
                self.write({"change_my_temp_level_name":res})
            #设置组件属性  - 公开 、需要邀请码、私有
            elif post_type=="set_my_temp":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                temp_id=self.json_body.get("temp_id")
                public_flag=self.json_body.get("public_flag")
                res=self.set_my_temp(user_id,dir1_id,dir2_id,temp_id,public_flag)
                self.write({"set_my_temp":res})
            #重置组件邀请码
            elif post_type=="set_my_temp_num":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                temp_id=self.json_body.get("temp_id")
                res=self.set_my_temp_num(user_id,dir1_id,dir2_id,temp_id)
                self.write({"set_my_temp_num":res})
            #更改组件的显示图标
            elif post_type=="change_temp_img":
                dir1_id=self.json_body.get("dir1_id")
                dir2_id=self.json_body.get("dir2_id")
                temp_id=self.json_body.get("temp_id")
                res=self.change_temp_img(user_id,dir1_id,dir2_id,temp_id)
                self.write({"change_temp_img":res})
        else:
            # print("dddddddddddddd",user_info)
            self.write(user_info)
    #查看项目参与者目录
    def project_user(self,project_dir,project_id):
        easyedit_userid = self.get_cookie("easyedit_userid")
        project_dir=self.json_body.get("project_dir")
        project_id=self.json_body.get("project_id")
        dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        res=user_db.db_obj.get(select_field=['id',"name"],condition_field={"id":[int(item) for item in other_lst]})
        res=res['data']
        res.sort(key=lambda item: item["id"]) 
        # print("...res:",res,other_lst)
        return {"project_user":res}
    #获取 我的项目 文件夹列表
    #res:[{"num":1,"name":"项目名1"},{"num":2,"name":"项目名2"}]
    def get_self_project_lst(self):
        res=[]
        easyedit_userid = self.get_cookie("easyedit_userid")
        self_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'
        for item in os.listdir(self_dir):
            # print(self_dir+os.sep+"config.yaml")
            with open(self_dir+os.sep+item+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            res.append({"num":int(item),'name':config__['name']})
        res.sort(key=lambda item: item["num"]) 
        return res
    #获取 他人项目 列表
    #res:[{"id":1,"name":"用户名2"},{"id":2,"name":"用户名2"}]
    def get_other_lst(self):
        res=[]
        easyedit_userid = self.get_cookie("easyedit_userid")
        other_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'
        res=user_db.db_obj.get(select_field=['id',"name"],condition_field={"id":[int(item) for item in os.listdir(other_dir)]})
        res=res['data']
        res.sort(key=lambda item: item["id"]) 
        return res
    #获取他人项目 某#获取 他人项目 列表
    def get_other_projects(self,other_id):
        res=[]
        easyedit_userid = self.get_cookie("easyedit_userid")
        other_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'+os.sep+other_id+os.sep+"projects"
        for item in os.listdir(other_dir):
            other_project=base_config['user_dir']+os.sep+other_id+os.sep+'self'+os.sep+"projects"+os.sep+item
            with open(other_project+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            res.append({"num":int(item),'name':config__['name']})
        res.sort(key=lambda item: item["num"]) 
        return res
    #获取我的项目 XXX目录下的所有项目 信息
    #res [{'num':1,"name":xxx，"other_lst":[],"last_time":sdaf}]
    def get_my_project_all(self,project_dir):
        res=[]
        easyedit_userid = self.get_cookie("easyedit_userid")
        self_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+project_dir+os.sep+"projects"
        for project_id in os.listdir(self_dir):
            with open(self_dir+os.sep+project_id+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            config__['num']=int(project_id)
            res.append(copy.copy(config__))
        res.sort(key=lambda item: item["num"]) 
        # print("fdadf",res)
        return {"get_my_project_all":res}
    
    #获取我的项目 目录下的
    #获取他人项目的所有目录
    def get_other_project_dir(self,other_id):
        res=[]
        easyedit_userid = self.get_cookie("easyedit_userid")
        other_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'+os.sep+other_id
        for item in os.listdir(other_dir):
            other_project=base_config['user_dir']+os.sep+other_id+os.sep+'self'+os.sep+item
            with open(other_project+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            res.append({"num":int(item),'name':config__['name']})
        res.sort(key=lambda item: item["num"]) 
        return res
    #获取他人项目project_id目录下的所有项目信息
    #res [{'num':1,"name":xxx}]
    def get_other_project_all(self,other_id,project_dir):
        res=[]
        easyedit_userid = self.get_cookie("easyedit_userid")
        other_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'+os.sep+other_id+os.sep+project_dir+os.sep+"projects"
        for project_id in os.listdir(other_dir):
            other_project=base_config['user_dir']+os.sep+other_id+os.sep+'self'+os.sep+project_dir+os.sep+"projects"+os.sep+project_id
            with open(other_project+os.sep+"config.yaml", 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            config__['num']=int(project_id)
            res.append(copy.copy(config__))
        res.sort(key=lambda item: item["num"]) 
        return {"get_other_project_all":res}
    #新建项目目录
    def create_project_dir(self,project_dir):
        try:
            val=[item['num']for item in self.get_self_project_lst()]
            now_max=1
            try:now_max=max(val)+1
            except:pass
            easyedit_userid = self.get_cookie("easyedit_userid")
            create_dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(now_max)
            os.makedirs(create_dir_path+os.sep+"projects")
            create_config_file=create_dir_path+os.sep+"config.yaml"
            with open(create_config_file, 'w') as file:  
                yaml.dump({"name":project_dir}, file, default_flow_style=False, sort_keys=False)  
            return {"name":project_dir,"num":now_max}
        except Exception as e:
            return {"type":"error","message":str(e)}
    #删除我的项目目录
    def del_project_dir(self,project_dir):
        easyedit_userid = self.get_cookie("easyedit_userid")
        del_dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)
        for project_id in os.listdir(del_dir_path):
            project_config_path=del_dir_path+os.sep+project_id+os.sep+"config.yaml"
            with open(project_config_path, 'r',encoding='utf-8') as f:
                config__ = yaml.load(f, Loader=yaml.FullLoader)
            other_lst=config__.get("other_lst")
            #删除所有参与项目的人 的数据
            if other_lst is not None:
                for other_id in other_lst:
                    other_dir=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'other'+os.sep+other_id
                    try:shutil.rmtree(other_dir+os.sep+"projects"+os.sep+project_id)    
                    except:pass
                    if len(os.listdir(other_dir+os.sep+"projects"))==0:
                        try:shutil.rmtree(other_dir)    
                        except:pass
        try:shutil.rmtree(del_dir_path)
        except:pass
        return {"type":"ok",'message':"删除成功"}
    #新建我的项目
    def create_project(self,project_dir,project_name):
        easyedit_userid = self.get_cookie("easyedit_userid")
        dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)
        test=self.get_my_project_all(project_dir)
        # print("##############",test,project_dir)
        val=[item['num']for item in self.get_my_project_all(project_dir)['get_my_project_all']]
        now_max=1
        try:now_max=max(val)+1
        except:pass
        create_dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+str(now_max)
        os.makedirs(create_dir_path)
        create_config_file=create_dir_path+os.sep+"config.yaml"
        yaml_val={"name":project_name,"other_lst":[],"last_time":time.time()}
        with open(create_config_file, 'w') as file:  
            yaml.dump(yaml_val, file, default_flow_style=False, sort_keys=False)  
        #创建项目的db文件夹
        db_dir=create_dir_path+os.sep+"db_dir"
        try:os.makedirs(db_dir)
        except:pass
        #项目初始数据
        
        新项目初始内容["project_name"]=project_name
        main_yaml_val=新项目初始内容
        #项目初始数据存放的 yaml
        config_yaml=create_dir_path+os.sep+"main.yaml"
        with open(config_yaml, 'w') as file:  
            yaml.dump(main_yaml_val, file, default_flow_style=False, sort_keys=False)  
        
        yaml_val['num']=now_max
        return yaml_val
    #修改项目名称
    def change_project(self,project_dir,project_id,project_name):
        easyedit_userid = self.get_cookie("easyedit_userid")
        dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+str(project_id)
        config_file=dir_path+os.sep+"config.yaml"
        yaml_val={"name":project_name,"other_lst":[],"last_time":time.time()}
        
        with open(config_file, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
            config__['name']=project_name
        with open(config_file, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
        return {"name":project_name,"num":project_id}
    #删除我的项目
    def del_project(self,project_dir,project_id):
    #添加别人参与我的项目
        easyedit_userid = self.get_cookie("easyedit_userid")
        del_dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=del_dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        #删除所有参与项目的人 的数据
        if other_lst is not None:
            for other_id in other_lst:
                other_dir=base_config['user_dir']+os.sep+str(other_id)+os.sep+'other'+os.sep+str(easyedit_userid)+os.sep+str(project_dir)
                try:shutil.rmtree(other_dir+os.sep+"projects"+os.sep+project_id)    
                except:pass
                if len(os.listdir(other_dir+os.sep+"projects"))==0:
                    try:shutil.rmtree(other_dir)    
                    except:pass
                d2=base_config['user_dir']+os.sep+str(other_id)+os.sep+'other'+os.sep+str(easyedit_userid)
                if len(os.listdir(d2))==0:
                    try:shutil.rmtree(d2)    
                    except:pass
        try:shutil.rmtree(del_dir_path)
        except:pass
        return {"type":"ok",'message':"删除成功","num":project_id}
    #添加别人参与我的项目
    def add_other_project(self,project_dir,project_id,other_id):
        easyedit_userid = self.get_cookie("easyedit_userid")
        if easyedit_userid==other_id:return {"type":"error","message":'不能添加自己'}
        dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        if other_id not in other_lst:
            other_lst.append(other_id)
        config__['other_lst']=other_lst
        with open(project_config_path, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
        #别人的项目文件夹
        
        dir_path=base_config['user_dir']+os.sep+other_id+os.sep+'other'+os.sep+easyedit_userid+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        try:os.makedirs(dir_path)
        except:pass
        
        res=user_db.db_obj.get(select_field=['id',"name"],condition_field={"id":[int(other_id)]})
        res=res['data'][0]
        return res
    #删除别人参与我的项目
    def del_other_project(self,project_dir,project_id,other_id,del_idx):
        easyedit_userid = self.get_cookie("easyedit_userid")
        dir_path=base_config['user_dir']+os.sep+easyedit_userid+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        try:other_lst.remove(other_id)
        except:pass
        config__['other_lst']=other_lst
        with open(project_config_path, 'w') as file:  
            yaml.dump(config__, file, default_flow_style=False, sort_keys=False)  
        return {"type":"ok",'message':"成功","del_idx":del_idx}
    #确认参与别人的项目
    def ok_add_other_project(self):
        other_id=self.json_body.get("other_id")
        ok_add_other_project=self.json_body.get("ok_add_other_project")
        res=self.ok_add_other_project(other_id,ok_add_other_project)
    #验证对方是否可以编辑目标项目
    @classmethod #类方法
    def check_user_project_edit(cls,easyedit_userid,user_id,project_dir,project_id):
        dir_path=base_config['user_dir']+os.sep+user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
        project_config_path=dir_path+os.sep+"config.yaml"
        with open(project_config_path, 'r',encoding='utf-8') as f:
            config__ = yaml.load(f, Loader=yaml.FullLoader)
        other_lst=config__.get("other_lst")
        if (user_id==easyedit_userid)or (easyedit_userid in other_lst):
            return True
        else:
            return False

#验证用户登录状态
class check_login(base_class):
    def post(self):
        login_flag,user_info=self.check_user()#验证登录
        if login_flag is True:
            self.write({"type":"ccccc"})
        else:
            self.write(user_info)
ed_dct={"ed":None}
# 存储所有客户端连接的集合  
num_dct={}
global_info={"user_db":user_db}
#验证用户是否可以对项目进行处理
def check_user_project_edit(easyedit_userid,user_id,project_dir,project_id):
    dir_path=base_config['user_dir']+os.sep+user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+project_id
    project_config_path=dir_path+os.sep+"config.yaml"
    with open(project_config_path, 'r',encoding='utf-8') as f:
        config__ = yaml.load(f, Loader=yaml.FullLoader)
    other_lst=config__.get("other_lst")
    if (user_id==easyedit_userid)or (easyedit_userid in other_lst):
        return True
    else:
        return False
kwargs_={
    "check_user_login_data":user_db.check_user_login_data,#判断用户 登录是否合法
    'check_user_project_edit':check_user_project_edit,#判断用户 是否可以对项目进行处理
    # 'edit_data':lambda :ed_dct['ed'].data#返回编辑数据
}
web_socket=auto_config(kwargs_)
web_socket_objects={web_socket}
web_socket_obj=None
def 将更新下发到所有用户(key,send_message):
    global web_socket,web_socket_obj
    # print("num_dct",web_socket.num_dct)
    objs__=web_socket.num_dct[key]["users"]
    
    web_socket.on_message2(web_socket_obj,send_message,key,objs__)
    # #同步到所有正在编辑当前项目的用户中 
    # for _num_ in objs__:
    #     # if _num_ !=web_socket_obj.num:
    #     web_socket_obj.return_client_by_num(_num_)['client'].write_message(send_message)
    # key=(user_id,project_dir,project_id)

class WebSocketHandler(tornado.websocket.WebSocketHandler):
    def get_ip(self):
        # self.request.remote_ip 
        ip = self.request.remote_ip
        # print("websocket ip:",ip)
        # if ip:  
        #     # 如果存在多个IP（由逗号分隔），通常取第一个  
        #     ip = ip.split(",")[0].strip()  
        # else:  
        #     # 如果没有X-Forwarded-For头，则使用remote_ip  
        #     ip = self.request.remote_ip  
        return ip
    def _____create_number(self):
        res=''
        for i in range(6):
          res=res+ str(random.randrange(0, 100000)).zfill(5)
        return res
    def create_num(self):
        global num_dct
        while 1:
            num=self._____create_number()
            if num not in num_dct:
                self.num=num
                num_dct[num]={'client':self,"time":time.time()}
                return
    def return_client_by_num(self,num):
        return num_dct[num]
    def delete_num(self):
        del num_dct[self.num]
    def check_origin(self, origin):
        # 允许跨域访问
        return True

    def open(self):
        global web_socket_obj
        if web_socket_obj is None:
            web_socket_obj=self
        # print("open websocoket")
        self.create_num()#创建连接唯一num
        for obj in web_socket_objects:
            try:
                # print("open websocoket 1")
                obj.open(self)
            except:pass
    def on_message(self, message):
        # print("on_message websocoket")
        # 处理从客户端发送的消息
        message = tornado.escape.json_decode(message)
        for obj in web_socket_objects:
            # print("on_message websocoket 1")
            try:obj.on_message(self,message)
            except Exception as e:print(str(e))

    def on_close(self):
        self.delete_num()#删除连接唯一num
        for obj in web_socket_objects:
            try:obj.on_close(self)
            except:pass

class login(tornado.web.RequestHandler):
    def get(self):  # 我们修改了这里
        """对应http的post请求方式"""
        with open(base_config['login'],'r',encoding='utf-8')as f:
            # print(f.read())
            self.write(f.read())
class project(tornado.web.RequestHandler):
    def get(self):  # 我们修改了这里
        """对应http的post请求方式"""
        with open(base_config['project'],'r',encoding='utf-8')as f:
            # print(f.read())
            self.write(f.read())
class home(tornado.web.RequestHandler):
    def get(self):  # 我们修改了这里
        """对应http的post请求方式"""
        with open(base_config['home'],'r',encoding='utf-8')as f:
            # print(f.read())
            self.write(f.read())

# class test(tornado.web.RequestHandler):
#     def get(self):  # 我们修改了这里
#         """对应http的post请求方式"""
#         with open(base_config['test'],'r',encoding='utf-8')as f:
#             # print(f.read())
            self.write(f.read())
class test2(tornado.web.RequestHandler):
    def get(self):  # 我们修改了这里
        
        uri = self.request.uri.split("?")[0]
        path_=uri[uri.find("test")+4:]
        print(path_)
        """对应http的post请求方式"""
        with open(base_config['test']+os.sep+'test'+path_+'.html','r',encoding='utf-8')as f:
            # print(f.read())
            self.write(f.read())
def set_http(process_type=False,url_lst=None,close_func=None,port=8888,ip='127.0.0.1',**k):
    global type_val,close_fun
    close_fun=close_func
    if url_lst is None:url_lst=[]
    type_val=process_type
    app = tornado.web.Application([
        *url_lst
        ],**k)
    ip_address = get_external_ip()
    print(f"服务访问网址为:http://{ip_address}:{port}/login")  
    app.listen(port)
    
    tornado.ioloop.IOLoop.current().start()

class all_http(tornado.web.RequestHandler):
    all_check_url={
        (0,0,0,0):False,
    }
    def get(self):  
        # 获取完整URI  
        uri = self.request.uri  
        # 获取路径（不含查询字符串）  
        path = self.request.path  
        # 获取所有查询字符串参数  
        query_args = self.request.query_arguments  
        query_args_dict = {k: self.get_query_argument(k) for k in query_args}  # 转换为字典  
  
        # 假设没有POST请求数据，这里仅作为示例  
        self.write(f"URI: {uri}\nPath: {path}\nQuery Args: {query_args_dict}")  
  
    def post(self):  
        # 获取POST请求的body参数（假设是表单数据）  
        body_arg = self.get_body_argument("key")  
        # 获取所有POST表单字段  
        body_args = self.get_body_arguments("key")  
  
        # 如果POST请求是JSON  
        if self.request.headers.get("Content-Type", "").startswith("application/json"):  
            json_data = tornado.escape.json_decode(self.request.body)  
            self.write(f"JSON Data: {json_data}")  
        else:  
            self.write(f"Body Arg: {body_arg}\nBody Args: {body_args}")  
  
run_dct={}
#运行服务
class None_v:pass
None_value=None_v()
class run_server(base_class):
    def __init__(self):
        {
            (0,0,0):{#项目作者 项目目录1 项目id
                0:{#流程图id为0
                    0:{#流程块id
                        "in_params":{
                            0:{#接收的第一个参数 

                            }
                        },#传入的参数
                        "out_params":{},#输出的参数 
                    }
                }
                }
        }
        self.params_dct={}#存放所有参数的字典

    def post(self):
        login_flag,user_info=self.check_user()#验证登录
        if login_flag is True:
            auther_id=0#项目作者id
            project_dir=0#项目目录id
            project_id=0#项目id
            flow_chat_id=0#当前要运行的id
            user_id=user_info['user_id']#当前正在操作的用户id
            flow_chat_info={}#当前要执行的数据
            for flow_chat_id in flow_chat_info:
                flow_chart_info={
                    "name":'x',
                    "id":"http",
                    "index":"x",
                    "type1":"default",
                    "x":1,
                    "y":1,
                    "out":{},
                    "in":{},
                }
                #传参
                params_in={}
                #如果是默认组件 则不生成 不注销 直接调用
                if flow_chart_info['type1']=='default':
                    pass
            self.write({"type":"ccccc"})
        else:
            self.write(user_info)



class flow(base_class):
    def __init__(self):
        {
            (0,0,0):{#项目作者 项目目录1 项目id
                0:{#流程图id为0
                    0:{#流程块id
                        "in_params":{
                            0:{#接收的第一个参数 

                            }
                        },#传入的参数
                        "out_params":{},#输出的参数 
                    }
                }
                }
        }
        self.params_dct={}#存放所有参数的字典

    def post(self):
        login_flag,user_info=self.check_user()#验证登录
        if login_flag is True:
            auther_id=0#项目作者id
            project_dir=0#项目目录id
            project_id=0#项目id
            flow_chat_id=0#当前要运行的id
            user_id=user_info['user_id']#当前正在操作的用户id
            flow_chat_info={}#当前要执行的数据

            #拷贝当前要执行的流程dict到运行中
            now_flow={
    "flow_chat_base_info": {
        "idx": 2,
        "flow_chat_name": "e"
    },
    "flow_chat_use_compontent": {
        "1": {
            "name": "mqtt初始化",
            "temp_type": "process",
            "in_kwargs": {
                "0": {
                    "name": "mqtt_address",
                    "note": "mqtt地址",
                    "default": "127.0.0.1",
                    "type": "str"
                },
                "1": {
                    "name": "mqtt_port",
                    "note": "mqtt端口",
                    "default": 1883,
                    "type": "int"
                },
                "2": {
                    "name": "mqtt_username",
                    "note": "mqtt登录用户名",
                    "default": "default",
                    "type": "str"
                },
                "3": {
                    "name": "mqtt_passwd",
                    "note": "mqtt登录密码",
                    "default": "default",
                    "type": "str"
                },
                "4": {
                    "name": "mqtt_client_name",
                    "note": "mqtt注册名称",
                    "default": "client_name",
                    "type": "str"
                },
                "5": {
                    "name": "recv_port",
                    "note": "进程接收其他进程消息的socket服务端口",
                    "default": 5555,
                    "type": "int"
                },
                "6": {
                    "name": "recv_ip",
                    "note": "进程接收其他进程消息的socket服务ip",
                    "default": "127.0.0.1",
                    "type": "str"
                }
            },
            "out_kwargs": {
                "0": {
                    "name": "进程通信端口",
                    "note": "mqtt进程的recv_port",
                    "type": "int"
                },
                "1": {
                    "name": "mqtt对象",
                    "note": "mqtt进程的recv_port",
                    "type": "int",
                    "out_params": {
                        "key1": "1",
                        "value1": {
                            "value": "0",
                            "label": "mqtt对象"
                        },
                        "key2": "0"
                    }
                }
            },
            "temp_name": "mqtt初始化",
            "x": 163.04998779296875,
            "y": 86.46665954589844,
            "out_idx": 1,
            "in_idx": 0,
            "out": {
                "1": {
                    "out_id": 2,
                    "out_key": 1,
                    "name": "mqtt初始化->收mqtt数据",
                    "out_params": {
                        "key1": "1",
                        "value1": {
                            "value": "0",
                            "label": "mqtt对象"
                        },
                        "key2": "0"
                    }
                }
            },
            "in": {}
        },
        "2": {
            "name": "收mqtt数据",
            "id": "基础组件_mqtt通信_收mqtt数据",
            "index": 0,
            "in_kwargs": {
                "0": {
                    "name": "mqtt对象",
                    "note": "mqtt初始化后传出的对象",
                    "default": "",
                    "type": "int",
                    "in_params": {
                        "key1": "1",
                        "value1": {
                            "value": "0",
                            "label": "mqtt对象"
                        },
                        "key2": "0"
                    }
                },
                "1": {
                    "name": "match_topic",
                    "note": "匹配topic",
                    "default": "test/#",
                    "type": "str"
                }
            },
            "out_kwargs": {
                "0": {
                    "name": "url_params",
                    "note": "路由参数如/aaa/bbb 则为['aaa','bbb']",
                    "type": "list"
                },
                "1": {
                    "name": "data",
                    "note": "传递的数据",
                    "type": "dict"
                }
            },
            "temp_name": "收mqtt数据",
            "x": 47.04998779296875,
            "y": 213.46665954589844,
            "out_idx": 0,
            "in_idx": 1,
            "out": {},
            "in": {
                "1": {
                    "in_id": 1,
                    "in_key": 1,
                    "name": "mqtt初始化->收mqtt数据"
                }
            }
        }
    }
}
            for flow_chat_id in flow_chat_info:
                flow_chart_info={
                    "name":'x',
                    "id":"http",
                    "index":"x",
                    "type1":"default",
                    "x":1,
                    "y":1,
                    "out":{},
                    "in":{},
                }
                #传参
                params_in={}
                #如果是默认组件 则不生成 不注销 直接调用
                if flow_chart_info['type1']=='default':
                    pass
            self.write({"type":"ccccc"})
        else:
            self.write(user_info)
print(pro)
前端组件数据库路径=pro+os.sep+'_web'+os.sep+"vue_template_store"
后端组件数据库路径=pro+os.sep+'_server'+os.sep+"flow_dir"
from _base_tool.python.组件库操作.查询组件 import main as 组件库操作_查询组件
from _base_tool.python.组件库操作.创建目录1 import main as 组件库操作_创建目录1
from _base_tool.python.组件库操作.创建目录2 import main as 组件库操作_创建目录2
from _base_tool.python.组件库操作.创建组件目录并获取目录 import main as 组件库操作_创建组件目录并获取目录
from _base_tool.python.组件库操作.创建组件目录新版本并获取目录 import main as 组件库操作_创建组件目录新版本并获取目录
from _base_tool.python.组件库操作.更新组件目录下的指定版本之获取路径 import main as 组件库操作_更新组件目录下的指定版本之获取路径
前端查询组件_obj=组件库操作_查询组件(前端组件数据库路径,'前端组件数据库')
前端创建目录1_obj=组件库操作_创建目录1(前端组件数据库路径,'前端组件数据库')
前端创建目录2_obj=组件库操作_创建目录2(前端组件数据库路径,'前端组件数据库')
前端创建组件目录并获取目录_obj=组件库操作_创建组件目录并获取目录(前端组件数据库路径,'前端组件数据库')
前端创建组件目录新版本并获取目录_obj=组件库操作_创建组件目录新版本并获取目录(前端组件数据库路径,'前端组件数据库')
前端更新组件目录下的指定版本之获取路径_obj=组件库操作_更新组件目录下的指定版本之获取路径(前端组件数据库路径,'前端组件数据库')

后端查询组件_obj=组件库操作_查询组件(后端组件数据库路径,'后端组件数据库')
后端创建目录1_obj=组件库操作_创建目录1(后端组件数据库路径,'后端组件数据库')
后端创建目录2_obj=组件库操作_创建目录2(后端组件数据库路径,'后端组件数据库')
后端创建组件目录并获取目录_obj=组件库操作_创建组件目录并获取目录(后端组件数据库路径,'后端组件数据库')
后端创建组件目录新版本并获取目录_obj=组件库操作_创建组件目录新版本并获取目录(后端组件数据库路径,'后端组件数据库')
后端更新组件目录下的指定版本之获取路径_obj=组件库操作_更新组件目录下的指定版本之获取路径(后端组件数据库路径,'后端组件数据库')
class select_temp2(base_class):
    def post(self):
        # type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        # if type_ is False:
        #     self.write(user_info)
        #     return
        try:
            num=int(self.json_body.get("num"))
            page=int(self.json_body.get("page"))
            res=后端查询组件_obj.run(num=num,page=page)
        except Exception as e:res={"type":"error","message":"后端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class create_temp2_dir1(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_name=self.json_body.get("dir1_name")
            res=后端创建目录1_obj.run(user_id,dir1_name)
        except Exception as e:res={"type":"error","message":"后端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class create_temp2_dir2(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_name=self.json_body.get("dir2_name")
            res=后端创建目录2_obj.run(user_id,dir1_id,dir2_name)
        except Exception as e:res={"type":"error","message":"后端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
              
    
class create_temp2_temp(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_id=self.json_body.get("dir2_id")
            temp_name=self.json_body.get("temp_name")
            temp_version_name=self.json_body.get("temp_version_name")
            res=后端创建组件目录并获取目录_obj.run(user_id,dir1_id,dir2_id,temp_name,temp_version_name)
        except Exception as e:res={"type":"error","message":"后端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class create_temp2_temp_history(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_id=self.json_body.get("dir2_id")
            temp_id=self.json_body.get("temp_id")
            temp_version_name=self.json_body.get("temp_version_name")
            res=后端创建组件目录新版本并获取目录_obj.run(user_id,dir1_id,dir2_id,temp_id,temp_version_name)
        except Exception as e:res={"type":"error","message":"后端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class update_temp2_temp_history(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_id=self.json_body.get("dir2_id")
            temp_id=self.json_body.get("temp_id")
            version_id=self.json_body.get("version_id")
            res=后端更新组件目录下的指定版本之获取路径_obj.run(user_id,dir1_id,dir2_id,temp_id,version_id)
        except Exception as e:res={"type":"error","message":"后端组件库操作_查询组件异常:"+str(e)}
        self.write(res)

    
class create_temp1_temp(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_id=self.json_body.get("dir2_id")
            temp_name=self.json_body.get("temp_name")
            temp_version_name=self.json_body.get("temp_version_name")
            res=前端创建组件目录并获取目录_obj.run(user_id,dir1_id,dir2_id,temp_name,temp_version_name)
        except Exception as e:res={"type":"error","message":"前端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class create_temp1_temp_history(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_id=self.json_body.get("dir2_id")
            temp_id=self.json_body.get("temp_id")
            temp_version_name=self.json_body.get("temp_version_name")
            res=前端创建组件目录新版本并获取目录_obj.run(user_id,dir1_id,dir2_id,temp_id,temp_version_name)
        except Exception as e:res={"type":"error","message":"前端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class update_temp1_temp_history(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_id=self.json_body.get("dir2_id")
            temp_id=self.json_body.get("temp_id")
            version_id=self.json_body.get("version_id")
            res=前端更新组件目录下的指定版本之获取路径_obj.run(user_id,dir1_id,dir2_id,temp_id,version_id)
        except Exception as e:res={"type":"error","message":"前端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
#########################

class select_temp1(base_class):

    # async def prepare(self):  
    #     # 在这里执行你的逻辑  
    #     should_continue = await self.custom_logic()  
    #     if not should_continue:  
    #         # 如果不需要继续处理，直接返回响应  
    #         self.set_status(400)  # 设置一个错误状态码  
    #         self.finish({"message": "Preprocessing failed, request not processed."})  
  
    def post(self):
        # type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        # if type_ is False:
        #     self.write(user_info)
        #     return
        try:
            num=int(self.json_body.get("num"))
            page=int(self.json_body.get("page"))
            res=前端查询组件_obj.run(num=num,page=page)
        except Exception as e:res={"type":"error","message":"前端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class create_temp1_dir1(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_name=self.json_body.get("dir1_name")
            res=前端创建目录1_obj.run(user_id,dir1_name)
        except Exception as e:res={"type":"error","message":"前端组件库操作_查询组件异常:"+str(e)}
        self.write(res)
class create_temp1_dir2(base_class):
    def post(self):
        type_,user_info=self.check_user()# return True,{"type":"success","message":"验证成功","user_id":easyedit_userid}# return False,{"type":"error","error_code":1,"message":"验证不通过"}
        if type_ is False:
            self.write(user_info)
            return
        try:
            user_id=self.json_body.get("user_id")
            dir1_id=self.json_body.get("dir1_id")
            dir2_name=self.json_body.get("dir2_name")
            res=前端创建目录2_obj.run(user_id,dir1_id,dir2_name)
        except Exception as e:res={"type":"error","message":"前端组件库操作_查询组件异常:"+str(e)}
        self.write(res)

#########################
_ui_store_path=os.path.join(pro,'_web','vue_template_store')
#获取用户的前端组件库目录1列表
class get_ui_dir1(base_class):
    def init_user_dir(self,user_dir):
        #初始化用户目录
        if not os.path.exists(user_dir):
            try:os.makedirs(user_dir)
            except:pass
        #初始化用户目录下的yaml配置文件
        yaml_path=os.path.join(user_dir,'main.yaml')
        if not os.path.exists(yaml_path):
            try:
                with open(yaml_path, 'w',encoding='utf-8') as file:  
                    yaml.dump({"index":0}, file, default_flow_style=False, allow_unicode=True)  
            except:pass
    def post(self):
        user_dir=_ui_store_path+os.sep+'a'+str(self.user_id)
        print("user_dir:",user_dir)
        self.init_user_dir(user_dir)
        print("初始化完成")
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(user_dir):
            dir_path=os.path.join(user_dir,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(user_dir,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_2_0",
                                    "deepcopy_data":{"name":data.get("name",'未命名')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)
#获取用户的前端组件库目录1列表
class add_ui_dir1(base_class):
    def init_user_dir(self,user_dir):
        #初始化用户目录
        if not os.path.exists(user_dir):
            try:os.makedirs(user_dir)
            except:pass
        #初始化用户目录下的yaml配置文件
        yaml_path=os.path.join(user_dir,'main.yaml')
        if not os.path.exists(yaml_path):
            try:
                with open(yaml_path, 'w',encoding='utf-8') as file:  
                    yaml.dump({"index":0}, file, default_flow_style=False, allow_unicode=True)  
            except:pass
    def post(self):
        user_dir=_ui_store_path+os.sep+'a'+str(self.user_id)
        self.init_user_dir(user_dir)
        name=self.json_body.get("name")
        yaml_path=os.path.join(user_dir,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建目录1文件夹
        dir1_path=user_dir+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(dir1_path)
        except:pass
        #创建目录1yaml
        yaml_path2=os.path.join(dir1_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"index":0,"name":name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass

        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_2_0",
                "deepcopy_data":{"name":name}
                },
                "dict":{

                }}
        })


#获取用户的前端组件库目录1列表
class get_ui_dir2(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        dir1_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(dir1_path):
            dir_path=os.path.join(dir1_path,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(dir1_path,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_3_0",
                                    "deepcopy_data":{"name":data.get("name",'未命名')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)
#添加用户组件-前端目录2
class add_ui_dir2(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir1_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)
        yaml_path=os.path.join(dir1_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建目录2文件夹
        dir2_path=dir1_path+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(dir2_path)
        except:pass
        #创建目录2yaml
        yaml_path2=os.path.join(dir2_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"index":0,"name":name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass

        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_3_0",
                "deepcopy_data":{"name":name}
                },
                "dict":{

                }}
        })
#更改用户组件-前端目录1 属性
class change_ui_dir1(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir1_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)
        yaml_path=os.path.join(dir1_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['name']=name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(data['index']):{
                "base_info":{
                "deepcopy_data":{"name":name}
                },
                }
        })



#获取用户的前端组件库组件列表
class get_ui_temp(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        dir2_id=self.json_body.get("dir2_id")
        dir2_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(dir2_path):
            dir_path=os.path.join(dir2_path,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(dir2_path,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_4_0",
                                    "deepcopy_data":{"name":data.get("name",'未命名')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)

#添加前端组件
class add_ui_temp(base_class):
    def post(self):
        global 前端组件数据库对象_obj
        self.create_db()

        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        dir2_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)
        yaml_path=os.path.join(dir2_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建目录2文件夹
        dir2_path=dir2_path+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(dir2_path)
        except:pass
        #创建组件版本数据文件夹
        version_path=dir2_path+os.sep+'history'
        try:
            os.makedirs(version_path)
        except:pass

        #创建目录2yaml
        yaml_path2=os.path.join(dir2_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"index":0,"name":name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        inde_=data['index']
        前端组件数据库对象_obj.post(info={'path':f'{self.user_id}-{dir1_id}-{dir2_id}-{inde_}','user_id':self.user_id,'dir1_id':dir1_id,"dir2_id":dir2_id,"temp_id":data['index'],"version":"0","temp_name":name})
        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_4_0",
                "deepcopy_data":{"name":name}
                },
                "dict":{

                }}
        })

    def create_db(self):
        global 前端组件数据库对象_obj
        if 前端组件数据库对象_obj is None:
            config={'前端组件数据库':{
                    'id':{
                                        '名称':'id',
                                        '备注':'自增id',
                                        '主键':True, 
                                        '自增长':True,
                                        '索引':False,
                                        '字段类型':'INTEGER',
                                        '字段长度':None,
                                        },
                    'path':{
                                        '名称':'路径',
                                        '备注':'组件存储路径',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,30],
                                        },
                    'user_id':{
                                        '名称':'用户id',
                                        '备注':'用户id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                            
                    'dir1_id':{
                                        '名称':'dir1_id',
                                        '备注':'目录1id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                            
                    'dir2_id':{
                                        '名称':'dir2_id',
                                        '备注':'目录2id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                    'temp_id':{
                                        '名称':'temp_id',
                                        '备注':'组件id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                    'version':{
                                        '名称':'组件版本',
                                        '备注':'组件的最高版本',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                            
                            
                        'temp_name':{
                                            '名称':'组件名称',
                                            '备注':'组件名称',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'TEXT',
                                            '字段长度':[0,30],
                                            },
                }}
            db_path=os.path.join(os.path.dirname(pro),'db_dir')
            前端组件数据库对象_obj=base_db(db_data=config,db_dir_path=db_path)
        
#修改前端目录2属性
class change_ui_dir2(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        dir2_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)
        yaml_path=os.path.join(dir2_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['name']=name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(data['index']):{
                "base_info":{
                "deepcopy_data":{"name":name}
                },
                }
        })



#获取用户的前端组件库组件版本列表
class get_ui_version(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        temp_history_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(temp_history_path):
            dir_path=os.path.join(temp_history_path,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(temp_history_path,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_5_0",
                                    "deepcopy_data":{"version_name":data.get("version_name",'未命名'),'version':dir_name.replace("a",'')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)
#添加前端组件版本
class add_ui_version(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        version_name=self.json_body.get("version_name")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        temp_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        temp_history_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'
        yaml_path=os.path.join(temp_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建版本文件夹
        version_path=temp_history_path+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(version_path)
        except:pass
        #创建版本文件夹 yaml
        yaml_path2=os.path.join(version_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"version":str(data['index']),"version_name":version_name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass

        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_5_0",
                "deepcopy_data":{"version_name":version_name,'version':str(data['index'])}
                },
                "dict":{

                }}
        })
#修改前端组件属性
class change_ui_temp(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        temp_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        yaml_path=os.path.join(temp_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['name']=name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(data['index']):{
                "base_info":{
                "deepcopy_data":{"name":name}
                },
                }
        })

#修改前端组件版本属性
class change_ui_version(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        version_name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        version_id=self.json_body.get("version_id")
        temp_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'+os.sep+'a'+str(version_id)
        yaml_path=os.path.join(temp_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['version_name']=version_name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(version_id):{
                "base_info":{
                "deepcopy_data":{"version_name":version_name}
                },
                }
        })


_flow_store_path=os.path.join(pro,'_server','flow_dir')
#获取用户的后端组件库目录1列表
class get_flow_dir1(base_class):
    def init_user_dir(self,user_dir):
        #初始化用户目录
        if not os.path.exists(user_dir):
            try:os.makedirs(user_dir)
            except:pass
        #初始化用户目录下的yaml配置文件
        yaml_path=os.path.join(user_dir,'main.yaml')
        if not os.path.exists(yaml_path):
            try:
                with open(yaml_path, 'w',encoding='utf-8') as file:  
                    yaml.dump({"index":0}, file, default_flow_style=False, allow_unicode=True)  
            except:pass
    def post(self):
        user_dir=_flow_store_path+os.sep+'a'+str(self.user_id)
        print("user_dir:",user_dir)
        self.init_user_dir(user_dir)
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(user_dir):
            dir_path=os.path.join(user_dir,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(user_dir,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_9_1",
                                    "deepcopy_data":{"name":data.get("name",'未命名')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)
#获取用户的后端组件库目录1列表
class add_flow_dir1(base_class):
    def init_user_dir(self,user_dir):
        #初始化用户目录
        if not os.path.exists(user_dir):
            try:os.makedirs(user_dir)
            except:pass
        #初始化用户目录下的yaml配置文件
        yaml_path=os.path.join(user_dir,'main.yaml')
        if not os.path.exists(yaml_path):
            try:
                with open(yaml_path, 'w',encoding='utf-8') as file:  
                    yaml.dump({"index":0}, file, default_flow_style=False, allow_unicode=True)  
            except:pass
    def post(self):
        user_dir=_flow_store_path+os.sep+'a'+str(self.user_id)
        self.init_user_dir(user_dir)
        name=self.json_body.get("name")
        yaml_path=os.path.join(user_dir,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建目录1文件夹
        dir1_path=user_dir+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(dir1_path)
        except:pass
        #创建目录1yaml
        yaml_path2=os.path.join(dir1_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"index":0,"name":name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass

        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_9_1",
                "deepcopy_data":{"name":name}
                },
                "dict":{

                }}
        })


#获取用户的后端组件库目录1列表
class get_flow_dir2(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        dir1_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(dir1_path):
            dir_path=os.path.join(dir1_path,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(dir1_path,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_10_1",
                                    "deepcopy_data":{"name":data.get("name",'未命名')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)
#添加用户组件-后端目录2
class add_flow_dir2(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir1_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)
        yaml_path=os.path.join(dir1_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建目录2文件夹
        dir2_path=dir1_path+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(dir2_path)
        except:pass
        #创建目录2yaml
        yaml_path2=os.path.join(dir2_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"index":0,"name":name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass

        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_10_1",
                "deepcopy_data":{"name":name}
                },
                "dict":{

                }}
        })
#更改用户组件-后端目录1 属性
class change_flow_dir1(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir1_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)
        yaml_path=os.path.join(dir1_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['name']=name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(data['index']):{
                "base_info":{
                "deepcopy_data":{"name":name}
                },
                }
        })



#获取用户的后端组件库组件列表
class get_flow_temp(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        dir2_id=self.json_body.get("dir2_id")
        dir2_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(dir2_path):
            dir_path=os.path.join(dir2_path,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(dir2_path,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_11_1",
                                    "deepcopy_data":{"name":data.get("name",'未命名')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)

#添加后端组件
class add_flow_temp(base_class):
    def post(self):
        global 后端组件数据库对象_obj
        self.create_db()

        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        dir2_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)
        yaml_path=os.path.join(dir2_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建目录2文件夹
        dir2_path=dir2_path+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(dir2_path)
        except:pass
        #创建组件版本数据文件夹
        version_path=dir2_path+os.sep+'history'
        try:
            os.makedirs(version_path)
        except:pass

        #创建目录2yaml
        yaml_path2=os.path.join(dir2_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"index":0,"name":name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        inde_=data['index']
        后端组件数据库对象_obj.post(info={'path':f'{self.user_id}-{dir1_id}-{dir2_id}-{inde_}','user_id':self.user_id,'dir1_id':dir1_id,"dir2_id":dir2_id,"temp_id":data['index'],"version":"0","temp_name":name})
        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_11_1",
                "deepcopy_data":{"name":name}
                },
                "dict":{

                }}
        })

    def create_db(self):
        global 后端组件数据库对象_obj
        if 后端组件数据库对象_obj is None:
            config={'后端组件数据库':{
                    'id':{
                                        '名称':'id',
                                        '备注':'自增id',
                                        '主键':True, 
                                        '自增长':True,
                                        '索引':False,
                                        '字段类型':'INTEGER',
                                        '字段长度':None,
                                        },
                    'path':{
                                        '名称':'路径',
                                        '备注':'组件存储路径',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,30],
                                        },
                    'user_id':{
                                        '名称':'用户id',
                                        '备注':'用户id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                            
                    'dir1_id':{
                                        '名称':'dir1_id',
                                        '备注':'目录1id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                            
                    'dir2_id':{
                                        '名称':'dir2_id',
                                        '备注':'目录2id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                    'temp_id':{
                                        '名称':'temp_id',
                                        '备注':'组件id',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                    'version':{
                                        '名称':'组件版本',
                                        '备注':'组件的最高版本',
                                        '主键':False, 
                                        '自增长':False,
                                        '索引':True,
                                        '字段类型':'TEXT',
                                        '字段长度':[0,10],
                                        },
                            
                            
                        'temp_name':{
                                            '名称':'组件名称',
                                            '备注':'组件名称',
                                            '主键':False, 
                                            '自增长':False,
                                            '索引':None,
                                            '字段类型':'TEXT',
                                            '字段长度':[0,30],
                                            },
                }}
            db_path=os.path.join(os.path.dirname(pro),'db_dir')
            后端组件数据库对象_obj=base_db(db_data=config,db_dir_path=db_path)
        
#修改后端目录2属性
class change_flow_dir2(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        dir2_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)
        yaml_path=os.path.join(dir2_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['name']=name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(data['index']):{
                "base_info":{
                "deepcopy_data":{"name":name}
                },
                }
        })



#获取用户的后端组件库组件版本列表
class get_flow_version(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        temp_history_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'
        res={"type":"okk","data":{}}
        for dir_name in os.listdir(temp_history_path):
            dir_path=os.path.join(temp_history_path,dir_name)
            if not os.path.isdir(dir_path):continue
            yaml_path=os.path.join(temp_history_path,dir_name,'main.yaml')
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
                res['data'][dir_name.replace("a","")]={
                                 "base_info":{
                                    "vue_name":"a_1_0_2_12_1",
                                    "deepcopy_data":{"version_name":data.get("version_name",'未命名'),'version':dir_name.replace("a",'')}
                                 },
                                 "dict":{

                                 }

                }
        self.write(res)
#添加后端组件版本
class add_flow_version(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        version_name=self.json_body.get("version_name")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        temp_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        temp_history_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'
        yaml_path=os.path.join(temp_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['index']=data["index"]+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        #创建版本文件夹
        version_path=temp_history_path+os.sep+'a'+str(data['index'])
        try:
            os.makedirs(version_path)
        except:pass
        #创建版本文件夹 yaml
        yaml_path2=os.path.join(version_path,'main.yaml')
        try:
            with open(yaml_path2, 'w',encoding='utf-8') as file:  
                yaml.dump({"version":str(data['index']),"version_name":version_name}, file, default_flow_style=False, allow_unicode=True)  
        except:pass

        self.write({
            str(data['index']):{
                "base_info":{
                "vue_name":"a_1_0_2_12_1",
                "deepcopy_data":{"version_name":version_name,'version':str(data['index'])}
                },
                "dict":{

                }}
        })
#修改后端组件属性
class change_flow_temp(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        temp_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        yaml_path=os.path.join(temp_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['name']=name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(data['index']):{
                "base_info":{
                "deepcopy_data":{"name":name}
                },
                }
        })

#修改后端组件版本属性
class change_flow_version(base_class):
    def post(self):
        dir1_id=self.json_body.get("dir1_id")
        version_name=self.json_body.get("name")
        dir2_id=self.json_body.get("dir2_id")
        temp_id=self.json_body.get("temp_id")
        version_id=self.json_body.get("version_id")
        temp_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'+os.sep+'a'+str(version_id)
        yaml_path=os.path.join(temp_path,'main.yaml')
        #读取用户目录下的yaml配置文件
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        #计数+1
        data['version_name']=version_name
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        self.write({
            str(version_id):{
                "base_info":{
                "deepcopy_data":{"version_name":version_name}
                },
                }
        })

#更新前端组件版本代码
from concurrent.futures import ThreadPoolExecutor
from tornado.concurrent import run_on_executor
# 创建一个线程池
executor = ThreadPoolExecutor(max_workers=4)
class update_ui_code(base_class):
    executor = executor
    async def post(self):
        print("start update")
        # 获取上传的文件
        
        objs = self.request.files.items()
        # 异步处理文件上传
        await self.handle_files(objs)
        self.write({"type":"success",'message':"上传成功"})
    def replace_text_in_files(self,src_dir, dst_dir):  
        # 如果目标目录不存在，则创建它  
        if not os.path.exists(dst_dir):  
            os.makedirs(dst_dir)  
        # 遍历源目录  
        for root, dirs, files in os.walk(src_dir):  
            # 构建目标目录的路径  
            dst_root = root.replace(src_dir, dst_dir, 1)  
            
            # 如果目标子目录不存在，则创建它  
            if not os.path.exists(dst_root):  
                os.makedirs(dst_root)  
    
            # 遍历文件  
            for file in files:  
                # 构建文件的完整路径  
                src_file = os.path.join(root, file)  
                dst_file = os.path.join(dst_root, file)  
                with open(src_file, 'rb') as f:  
                    content = f.read()  
                # 将修改后的内容写入到目标文件  
                with open(dst_file, 'wb') as f:  
                    f.write(content) 
    def rm_dir(self,dir_path):
        try:
            # 递归地删除目录及其所有内容  
            shutil.rmtree(dir_path)  
        except:pass

    @run_on_executor
    def handle_files(self, objs):
        dir1_id=str(self._list_bytes2str(self.request.arguments.get("dir1_id")))
        dir2_id=str(self._list_bytes2str(self.request.arguments.get("dir2_id")))
        temp_id=str(self._list_bytes2str(self.request.arguments.get("temp_id")  ))
        version_id=str(self._list_bytes2str(self.request.arguments.get("version_id")))
        version_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'+os.sep+'a'+version_id
        file_count=1
        # 处理文件的逻辑
        for _name, file_info in objs:  
            for file_meta in file_info:  
                ppp=str(self._list_bytes2str(self.request.arguments.get(f"file_path{file_count}")  ))
                if "\\" in ppp:
                    parts=ppp.split("\\")[1:]
                else:
                    parts=ppp.split("/")[1:]
                # 获取文件名（这里可能包含路径信息）  
                file_count+=1
                # print(parts)
                body=file_meta['body']
                dir_path=version_path
                if len(parts) > 1:
                    # 重建目录结构  
                    dir_path = os.path.join(version_path, *parts[:-1])  
                    # print("组织目录",dir_path)
                    try:
                        if not os.path.exists(dir_path):  
                            os.makedirs(dir_path)  
                    except:pass 
                filename = parts[-1]
                # 计算文件的完整保存路径  
                file_path = os.path.join(dir_path, filename)
                # print(file_path)
                try:
                    # 将文件内容读取为字符串  
                    file_content = body.decode('utf-8')
                    # 替换字符串  
                    new_body = file_content.replace('temp__ea', f'a_{self.user_id}_{dir1_id}_{dir2_id}_{temp_id}_{version_id}')  
                    
                    # 写入文件  
                    with open(file_path, 'wb') as f:  
                        f.write(new_body.encode('utf-8') )
                except Exception as e:
                    print("eeee:",e)
                    try:
                        # 写入文件  
                        with open(file_path, 'wb') as f:  
                            f.write(body)
                    except Exception as e:
                        print("上传组件之保存文件错误",e)
        #拷贝目录所有内容到备份目录中
        temp_p=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        #读取当前保存的数量
        yaml_path=os.path.join(temp_p,'save.yaml')
        try:
            #读取用户目录下的yaml配置文件
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
        except:
            data={}
        data["save_index"]=data.get("save_index",0)+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        save_dir=temp_p+os.sep+'save'+os.sep+str(data["save_index"])
        try:
            os.makedirs(save_dir)
        except:pass
        self.replace_text_in_files(version_path,save_dir)
        if(data["save_index"]>10):
            self.rm_dir(temp_p+os.sep+'save'+str(data["save_index"]-10))
        return "Files processed"
class update_flow_code(base_class):
    executor = executor
    async def post(self):
        # 获取上传的文件
        
        objs = self.request.files.items()
        # 异步处理文件上传
        await self.handle_files(objs)
        self.write({"type":"success",'message':"上传成功"})
    def replace_text_in_files(self,src_dir, dst_dir):  
        # 如果目标目录不存在，则创建它  
        if not os.path.exists(dst_dir):  
            os.makedirs(dst_dir)  
    
        # 遍历源目录  
        for root, dirs, files in os.walk(src_dir):  
            # 构建目标目录的路径  
            dst_root = root.replace(src_dir, dst_dir, 1)  
            
            # 如果目标子目录不存在，则创建它  
            if not os.path.exists(dst_root):  
                os.makedirs(dst_root)  
    
            # 遍历文件  
            for file in files:  
                # 构建文件的完整路径  
                src_file = os.path.join(root, file)  
                dst_file = os.path.join(dst_root, file)  
                with open(src_file, 'rb') as f:  
                    content = f.read()  
                # 将修改后的内容写入到目标文件  
                with open(dst_file, 'wb') as f:  
                    f.write(content) 
    def rm_dir(self,dir_path):
        try:
            # 递归地删除目录及其所有内容  
            shutil.rmtree(dir_path)  
        except:pass

    @run_on_executor
    def handle_files(self, objs):
        dir1_id=str(self._list_bytes2str(self.request.arguments.get("dir1_id")))
        dir2_id=str(self._list_bytes2str(self.request.arguments.get("dir2_id")))
        temp_id=str(self._list_bytes2str(self.request.arguments.get("temp_id")  ))
        version_id=str(self._list_bytes2str(self.request.arguments.get("version_id")))
        version_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)+os.sep+'history'+os.sep+'a'+version_id
        file_count=1
        # 处理文件的逻辑
        for _name, file_info in objs:  
            for file_meta in file_info:  
                ppp=str(self._list_bytes2str(self.request.arguments.get(f"file_path{file_count}")  ))
                if "\\" in ppp:
                    parts=ppp.split("\\")[1:]
                else:
                    parts=ppp.split("/")[1:]
                # 获取文件名（这里可能包含路径信息）  
                file_count+=1
                # print(parts)
                body=file_meta['body']
                dir_path=version_path
                if len(parts) > 1:
                    # 重建目录结构  
                    dir_path = os.path.join(version_path, *parts[:-1])  
                    # print("组织目录",dir_path)
                    try:
                        if not os.path.exists(dir_path):  
                            os.makedirs(dir_path)  
                    except:pass 
                filename = parts[-1]  
                # 计算文件的完整保存路径  
                file_path = os.path.join(dir_path, filename)  
                # print(file_path)
                try:
                    # 将文件内容读取为字符串  
                    file_content = body.decode('utf-8')
                    # 替换字符串  
                    new_body = file_content.replace('temp__ea', f'a_{self.user_id}_{dir1_id}_{dir2_id}_{temp_id}_{version_id}')  
                    
                    # 写入文件  
                    with open(file_path, 'wb') as f:  
                        f.write(new_body.encode('utf-8') )
                except Exception as e:
                    print("eeee:",e)
                    try:
                        # 写入文件  
                        with open(file_path, 'wb') as f:  
                            f.write(body)
                    except Exception as e:
                        print("上传组件之保存文件错误",e)
        #拷贝目录所有内容到备份目录中
        temp_p=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        #读取当前保存的数量
        yaml_path=os.path.join(temp_p,'save.yaml')
        try:
            #读取用户目录下的yaml配置文件
            with open(yaml_path, 'r',encoding='utf-8') as file:  
                data = yaml.safe_load(file)
        except:
            data={}
        data["save_index"]=data.get("save_index",0)+1
        try:
            with open(yaml_path, 'w',encoding='utf-8') as file:  
                yaml.dump(data, file, default_flow_style=False, allow_unicode=True)  
        except:pass
        save_dir=temp_p+os.sep+'save'+os.sep+str(data["save_index"])
        try:
            os.makedirs(save_dir)
        except:pass
        self.replace_text_in_files(version_path,save_dir)
        if(data["save_index"]>10):
            self.rm_dir(temp_p+os.sep+'save'+str(data["save_index"]-10))
        return "Files processed"

import aiofiles  
import tornado.ioloop  
import tornado.web  
#当前正在下载的
now_down_dct={

}
now_down_lst=[]
#限制最大下载量
now_down_max=4
#最大等待下载数量
now_wait_max=200
#正在排队下载的
now_wait_lst=[]
#最大超时未下载时间(超出则清除)
max_time=10
#代码下载服务
import zipfile  

class download_ui_code(base_class):
    def replace_text_in_files(self,src_dir, dst_dir, replace_from, replace_to="temp__ea"):  
        # 如果目标目录不存在，则创建它  
        if not os.path.exists(dst_dir):  
            os.makedirs(dst_dir)  
    
        # 遍历源目录  
        for root, dirs, files in os.walk(src_dir):  
            # 构建目标目录的路径  
            dst_root = root.replace(src_dir, dst_dir, 1)  
            
            # 如果目标子目录不存在，则创建它  
            if not os.path.exists(dst_root):  
                os.makedirs(dst_root)  
    
            # 遍历文件  
            for file in files:  
                # 构建文件的完整路径  
                src_file = os.path.join(root, file)  
                dst_file = os.path.join(dst_root, file)  
                try:
                    # 只处理文本文件（可以根据需要调整扩展名）  
                    with open(src_file, 'r', encoding='utf-8') as f:  
                        content = f.read()  

                    # 替换文本内容  
                    new_content = content.replace(replace_from, replace_to)  

                    # 将修改后的内容写入到目标文件  
                    with open(dst_file, 'w', encoding='utf-8') as f:  
                        f.write(new_content)  
                except: 
                    with open(src_file, 'rb') as f:  
                        content = f.read()  
                    # 将修改后的内容写入到目标文件  
                    with open(dst_file, 'wb') as f:  
                        f.write(content) 
    def zip_folder(self,folder_path, output_zip_path):  
        '''
        #压缩文件夹为ZIP文件  
        #:param folder_path: 要压缩的文件夹路径  
        #:param output_zip_path: 输出的ZIP文件路径  
        '''
        with zipfile.ZipFile(output_zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:  
            for root, dirs, files in os.walk(folder_path):  
                for file in files:  
                    file_path = os.path.join(root, file)  
                    # 获取文件相对于文件夹路径的相对路径  
                    arcname = os.path.relpath(file_path, start=folder_path)
                    
                    zipf.write(file_path, arcname) 
    async def post(self):  
        down_user_id=str(self.json_body.get("down_user_id"))
        dir1_id=str(self.json_body.get("dir1_id"))
        dir2_id=str(self.json_body.get("dir2_id"))
        temp_id=str(self.json_body.get("temp_id"))
        version_id=str(self.json_body.get("version_id"))
        request_id=str(self.json_body.get("request_id"))
        down_id= f"{self.user_id}.{down_user_id}.{dir1_id}.{dir2_id}.{temp_id}.{version_id}.{request_id}"
        print("down_id",down_id)
        #如果超过最大排队数量 直接返回需要等待 now_wait_max+
        if len(now_wait_lst)>now_wait_max:
            print("等待",now_wait_max,'+')
            self.write({"type":"wait","num":str(now_wait_max)+'+'})
            return
        #加入待下载列表
        now_time=time.time()
        obj={"id":down_id,"time":now_time}
        now_wait_lst.append(obj)

        #清除超时未请求下载数据
        while len(now_wait_lst):
            if now_wait_lst[0]['time']+max_time<now_time:
                now_wait_lst.pop(0)
            else:
                break
        # print("如果当前不处在排队第一位置 那么返回需要等待 now_wait_max")
        if now_wait_lst[0]['id']!=down_id:
            # print("等待",len(now_wait_lst))
            self.write({"type":"wait","num":len(now_wait_lst)})
            return
        # print("如果正在下载的数量已达到最大 那么返回需要等待 1")
        if len(now_down_dct.keys())>=now_down_max:
            # print("等待",'1')
            self.write({"type":"wait","num":'1'})
            return
        # print("清除自身在待下载队列的信息 存储入正在下载队列")
        wait_obj=now_wait_lst.pop(0)
        now_down_dct[wait_obj['id']]=wait_obj
        #生成压缩文件夹
        save_dir=os.path.join(os.path.dirname(pro),'now_download','download_code')
        if not os.path.isdir(save_dir):
            try:
                os.makedirs(save_dir)
            except:pass
        #保存路径 名称
        dir_path=_ui_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        yaml_path=os.path.join(dir_path,'main.yaml')
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        obj['name']=f"{data['name']}.{version_id}.zip"
        obj['name2']=f"{down_id}_{data['name']}.{version_id}.zip"
        obj['dir_path']=dir_path+os.sep+'history'+os.sep+'a'+version_id
        obj['copy_path']=save_dir+os.sep+down_id
        obj['zip_path']=save_dir+os.sep+obj['name2']
        #拷贝目录并替换 组件id为模板
        self.replace_text_in_files(obj['dir_path'],obj['copy_path'],f'a_{down_user_id}_{dir1_id}_{dir2_id}_{temp_id}_{version_id}')
        #生成zip文件
        self.zip_folder(obj['copy_path'],obj['zip_path'])
        # print("返回可以下载信号")
        self.write({"type":"ok","down_url":f'/start_download/{down_id}'})
        return
class download_flow_code(base_class):
    def replace_text_in_files(self,src_dir, dst_dir, replace_from, replace_to="temp__ea"):  
        # 如果目标目录不存在，则创建它  
        if not os.path.exists(dst_dir):  
            os.makedirs(dst_dir)  
    
        # 遍历源目录  
        for root, dirs, files in os.walk(src_dir):  
            # 构建目标目录的路径  
            dst_root = root.replace(src_dir, dst_dir, 1)  
            
            # 如果目标子目录不存在，则创建它  
            if not os.path.exists(dst_root):  
                os.makedirs(dst_root)  
    
            # 遍历文件  
            for file in files:  
                # 构建文件的完整路径  
                src_file = os.path.join(root, file)  
                dst_file = os.path.join(dst_root, file)  
                try:
                    # 只处理文本文件（可以根据需要调整扩展名）  
                    with open(src_file, 'r', encoding='utf-8') as f:  
                        content = f.read()  

                    # 替换文本内容  
                    new_content = content.replace(replace_from, replace_to)  

                    # 将修改后的内容写入到目标文件  
                    with open(dst_file, 'w', encoding='utf-8') as f:  
                        f.write(new_content)  
                except: 
                    with open(src_file, 'rb') as f:  
                        content = f.read()  
                    # 将修改后的内容写入到目标文件  
                    with open(dst_file, 'wb') as f:  
                        f.write(content) 
    def zip_folder(self,folder_path, output_zip_path):  
        '''
        #压缩文件夹为ZIP文件  
        #:param folder_path: 要压缩的文件夹路径  
        #:param output_zip_path: 输出的ZIP文件路径  
        '''
        with zipfile.ZipFile(output_zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:  
            for root, dirs, files in os.walk(folder_path):  
                for file in files:  
                    file_path = os.path.join(root, file)  
                    # 获取文件相对于文件夹路径的相对路径  
                    arcname = os.path.relpath(file_path, start=folder_path)
                    
                    zipf.write(file_path, arcname) 
    async def post(self):  
        down_user_id=str(self.json_body.get("down_user_id"))
        dir1_id=str(self.json_body.get("dir1_id"))
        dir2_id=str(self.json_body.get("dir2_id"))
        temp_id=str(self.json_body.get("temp_id"))
        version_id=str(self.json_body.get("version_id"))
        request_id=str(self.json_body.get("request_id"))
        down_id= f"{self.user_id}.{down_user_id}.{dir1_id}.{dir2_id}.{temp_id}.{version_id}.{request_id}"
        print("down_id",down_id)
        #如果超过最大排队数量 直接返回需要等待 now_wait_max+
        if len(now_wait_lst)>now_wait_max:
            print("等待",now_wait_max,'+')
            self.write({"type":"wait","num":str(now_wait_max)+'+'})
            return
        #加入待下载列表
        now_time=time.time()
        obj={"id":down_id,"time":now_time}
        now_wait_lst.append(obj)

        #清除超时未请求下载数据
        while len(now_wait_lst):
            if now_wait_lst[0]['time']+max_time<now_time:
                now_wait_lst.pop(0)
            else:
                break
        # print("如果当前不处在排队第一位置 那么返回需要等待 now_wait_max")
        if now_wait_lst[0]['id']!=down_id:
            # print("等待",len(now_wait_lst))
            self.write({"type":"wait","num":len(now_wait_lst)})
            return
        # print("如果正在下载的数量已达到最大 那么返回需要等待 1")
        if len(now_down_dct.keys())>=now_down_max:
            # print("等待",'1')
            self.write({"type":"wait","num":'1'})
            return
        # print("清除自身在待下载队列的信息 存储入正在下载队列")
        wait_obj=now_wait_lst.pop(0)
        now_down_dct[wait_obj['id']]=wait_obj
        #生成压缩文件夹
        save_dir=os.path.join(os.path.dirname(pro),'now_download','download_code')
        if not os.path.isdir(save_dir):
            try:
                os.makedirs(save_dir)
            except:pass
        #保存路径 名称
        dir_path=_flow_store_path+os.sep+'a'+str(self.user_id)+os.sep+"a"+str(dir1_id)+os.sep+"a"+str(dir2_id)+os.sep+'a'+str(temp_id)
        yaml_path=os.path.join(dir_path,'main.yaml')
        with open(yaml_path, 'r',encoding='utf-8') as file:  
            data = yaml.safe_load(file)
        obj['name']=f"{data['name']}.{version_id}.zip"
        obj['name2']=f"{down_id}_{data['name']}.{version_id}.zip"
        obj['dir_path']=dir_path+os.sep+'history'+os.sep+'a'+version_id
        obj['copy_path']=save_dir+os.sep+down_id
        obj['zip_path']=save_dir+os.sep+obj['name2']
        #拷贝目录并替换 组件id为模板
        self.replace_text_in_files(obj['dir_path'],obj['copy_path'],f'a_{down_user_id}_{dir1_id}_{dir2_id}_{temp_id}_{version_id}')
        #生成zip文件
        self.zip_folder(obj['copy_path'],obj['zip_path'])
        # print("返回可以下载信号")
        self.write({"type":"ok","down_url":f'/start_download/{down_id}'})
        return


import urllib.parse  
  
import shutil  
class start_download(tornado.web.RequestHandler):  
    def rm_dir(self,dir_path):
        # 递归地删除目录及其所有内容  
        try:
            # 递归地删除目录及其所有内容  
            shutil.rmtree(dir_path)  
        except:print("删除失败",dir_path)
    def rm_file(self,file_path):
        try:
            os.remove(file_path)  
        except:pass
    async def get(self,request_id):  
        try:
            obj=now_down_dct[request_id]
            # head_=f'attachment; filename="{obj['name']}"'
            # head_=f'attachment; filename="test.zip"'
            filename = obj['name']
            filename_encoded = urllib.parse.quote(filename, safe='')  
            head_ = f'attachment; filename*=UTF-8\'\'{filename_encoded}'  
            # print(head_)
            # print("下载",len(now_down_dct.keys()))
            self.set_header('Content-Type', 'application/zip')  
            self.set_header('Content-Disposition', head_)
            print(obj['zip_path'])
            async with aiofiles.open(obj['zip_path'], 'rb') as f:  
                while True:  
                    chunk = await f.read(4096)  # 异步读取文件块  
                    if not chunk:  
                        break  
                    self.write(chunk)  
                    try:
                        await self.flush()  # 确保数据被发送到客户端  
                    except:
                        break
            del now_down_dct[request_id]
            self.rm_dir(obj['copy_path'])
            self.rm_file(obj['zip_path'])
            self.finish()
        except:self.write("")
class paste_flow_dir1(base_class):#粘贴后端目录1
    def post(self):
        text=str(self.json_body.get("text"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        # try:
        目录数据=获取目录1的结构数据("后端",text)
        send_message={
"type":"change_data",
"data_type":"set_list",
"update_params":[

            {
            "name":'@add_index',
            "path":'flow_chat_config.dict.2.base_info.index',
            "use":"++s"
            }
],
"postput":[
{
    'path':'flow_chat_config.dict.2.dict.@add_index',
    'data':目录数据
},
#更新
{
    'path':'flow_chat_config.dict.2.base_info',
    'data':{"index":"@add_index"}
},
],
}
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})
        # except:
        #     self.write({"type":"error","message":"异常"})
class paste_flow_dir2(base_class):#粘贴后按目录2
    def post(self):
        text=str(self.json_body.get("text"))
        key=str(self.json_body.get("key"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        dir1_id=key.split(".")[-1]
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        # try:
        目录数据=获取目录2的结构数据("后端",text)
        send_message={
"type":"change_data",
"data_type":"set_list",
"update_params":[

            {
            "name":'@add_index',
            "path":f'flow_chat_config.dict.2.dict.{dir1_id}.base_info.index',
            "use":"++s"
            }
],
"postput":[
{
    'path':f'flow_chat_config.dict.2.dict.{dir1_id}.dict.@add_index',
    'data':目录数据
},
#更新
{
    'path':f'flow_chat_config.dict.2.dict.{dir1_id}.base_info',
    'data':{"index":"@add_index"}
},
],
}
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})
class paste_flow_temp(base_class):    
    def post(self):
        text=str(self.json_body.get("text"))
        key=str(self.json_body.get("key"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        print('key',key)
        dir1_id=key.split(".")[-2]
        dir2_id=key.split(".")[-1]
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        try:
            目录数据=获取组件的结构数据("后端",text)
        except:
            self.write({"type":"error","message":"组件获取异常"})
            return
        send_message={
"type":"change_data",
"data_type":"set_list",
"update_params":[

            {
            "name":'@add_index',
            "path":f'flow_chat_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.base_info.index',
            "use":"++s"
            }
],
"postput":[
{
    'path':f'flow_chat_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.dict.@add_index',
    'data':目录数据
},
#更新
{
    'path':f'flow_chat_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.base_info',
    'data':{"index":"@add_index"}
},
],
}
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})

class change_use_flow_version(base_class):
    def post(self):
        value=str(self.json_body.get("value"))
        path_=str(self.json_body.get("path"))
        key=str(self.json_body.get("key"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        dir1_id=path_.split(".")[-3]
        dir2_id=path_.split(".")[-2]
        temp_id=path_.split(".")[-1]
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        # try:
        try:
            print("""'_'.join(key.split("_")[:-1]+[value])""",'_'.join(key.split("_")[:-1]+[value]))
            目录数据=获取组件的结构数据("后端",'_'.join(key.split("_")[:-1]+[value]))
        except:
            self.write({"type":"error","message":"组件获取异常"})
            return
        send_message={
                "type":"change_data",
                "data_type":"set_list",
                "clear":[
                    {'path':f'flow_chat_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.dict.{temp_id}.base_info.deepcopy_data.info',}
                ],
                "postput":[
                {
                    'path':f'flow_chat_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.dict.{temp_id}.base_info.deepcopy_data',
                    'data':目录数据['base_info']['deepcopy_data']
                },
                ],
                }
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})

class paste_page_dir1(base_class):#粘贴后端目录1
    def post(self):
        text=str(self.json_body.get("text"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        # try:
        目录数据=获取目录1的结构数据("前端",text)
        send_message={
"type":"change_data",
"data_type":"set_list",
"update_params":[

            {
            "name":'@add_index',
            "path":'page_config.dict.2.base_info.index',
            "use":"++s"
            }
],
"postput":[
{
    'path':'page_config.dict.2.dict.@add_index',
    'data':目录数据
},
#更新
{
    'path':'page_config.dict.2.base_info',
    'data':{"index":"@add_index"}
},
],
}
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})
        # except:
        #     self.write({"type":"error","message":"异常"})
class paste_page_dir2(base_class):#粘贴后按目录2
    def post(self):
        text=str(self.json_body.get("text"))
        key=str(self.json_body.get("key"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        dir1_id=key.split(".")[-1]
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        # try:
        目录数据=获取目录2的结构数据("前端",text)
        send_message={
"type":"change_data",
"data_type":"set_list",
"update_params":[

            {
            "name":'@add_index',
            "path":f'page_config.dict.2.dict.{dir1_id}.base_info.index',
            "use":"++s"
            }
],
"postput":[
{
    'path':f'page_config.dict.2.dict.{dir1_id}.dict.@add_index',
    'data':目录数据
},
#更新
{
    'path':f'page_config.dict.2.dict.{dir1_id}.base_info',
    'data':{"index":"@add_index"}
},
],
}
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})
class paste_page_temp(base_class):    
    def post(self):
        text=str(self.json_body.get("text"))
        key=str(self.json_body.get("key"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        print('key',key)
        dir1_id=key.split(".")[-2]
        dir2_id=key.split(".")[-1]
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        try:
            目录数据=获取组件的结构数据("前端",text)
        except:
            self.write({"type":"error","message":"组件获取异常"})
            return
        send_message={
"type":"change_data",
"data_type":"set_list",
"update_params":[

            {
            "name":'@add_index',
            "path":f'page_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.base_info.index',
            "use":"++s"
            }
],
"postput":[
{
    'path':f'page_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.dict.@add_index',
    'data':目录数据
},
#更新
{
    'path':f'page_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.base_info',
    'data':{"index":"@add_index"}
},
],
}
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})

class change_use_page_version(base_class):
    def post(self):
        value=str(self.json_body.get("value"))
        path_=str(self.json_body.get("path"))
        key=str(self.json_body.get("key"))
        user_id=str(self.json_body.get("user_id"))
        project_dir=str(self.json_body.get("project_dir"))
        project_id=str(self.json_body.get("project_id"))
        dir1_id=path_.split(".")[-3]
        dir2_id=path_.split(".")[-2]
        temp_id=path_.split(".")[-1]
        #验证当前用户是否拥有编辑此项目的权限
        flag=check_user_project_edit(self.user_id,user_id,project_dir,project_id)
        if flag is not True:
            self.write({"type":"error","message":"没有权限对此项目进行操作"})
            return
        # try:
        try:
            print("""'_'.join(key.split("_")[:-1]+[value])""",'_'.join(key.split("_")[:-1]+[value]))
            目录数据=获取组件的结构数据("前端",'_'.join(key.split("_")[:-1]+[value]))
        except:
            self.write({"type":"error","message":"组件获取异常"})
            return
        send_message={
                "type":"change_data",
                "data_type":"set_list",
                "clear":[
                    {'path':f'page_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.dict.{temp_id}.base_info.deepcopy_data.info',}
                ],
                "postput":[
                {
                    'path':f'page_config.dict.2.dict.{dir1_id}.dict.{dir2_id}.dict.{temp_id}.base_info.deepcopy_data',
                    'data':目录数据['base_info']['deepcopy_data']
                },
                ],
                }
        key=(user_id,project_dir,project_id)
        将更新下发到所有用户(key,send_message)
        self.write({"type":"okk"})
import hashlib
class read_temp_png(base_class):
    path_dct={
        "page":os.path.join(pro,"_web","vue_template_store"),
        "flow":os.path.join(pro,"_server","flow_dir")
    }
    static_path=os.path.join(pro,"_static_dir","__0__.png")
    def get(self):
        # 从请求参数中获取PNG文件路径
        temp_id = self.get_argument('temp_id', None)#组件id
        print("type:",self.get_argument('type', None))
        base_path = self.path_dct.get(self.get_argument('type', None))
        print("base_path:",base_path)
        file_path=base_path+os.sep+os.sep.join(["a"+item for item in temp_id.split("_")[1:]])+os.sep+'main.png'
        if not base_path:
            self.set_status(400)
            self.write({"error": "Invalid file type"})
            self.finish()
            return
        if not file_path :
            self.set_status(400)
            self.write({"error": "Invalid file path"})
            self.finish()
            return
        if not os.path.isfile(file_path):
            file_path=self.static_path
        # 计算文件的ETag（用于缓存验证）
        file_etag = hashlib.md5(file_path.encode('utf-8')).hexdigest()
        # 检查If-None-Match头以确定是否使用缓存
        if_none_match = self.request.headers.get('If-None-Match', None)
        if if_none_match == file_etag:
            self.set_status(304)  # Not Modified
            self.finish()
            return
        
        # 设置响应头
        self.set_header('ETag', file_etag)
        self.set_header('Content-Type', 'image/png')
        self.set_header('Cache-Control', 'public, max-age=31536000')  # 1年缓存
        self.set_header('Expires', time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(time.time() + 31536000)))
        # 读取并发送PNG文件内容
        with open(file_path, 'rb') as f:
            self.write(f.read())
        self.finish()

class show_page(tornado.web.RequestHandler):
    def get(self):
        user_id = self.get_argument('user_id', None)#组件id
        project_dir = self.get_argument('project_dir', None)#组件id
        project_id = self.get_argument('project_id', None)#组件id
        page_id = self.get_argument('page_id', None)#组件id
        create_dir_path=base_config['user_dir']+os.sep+user_id+os.sep+'self'+os.sep+str(project_dir)+os.sep+"projects"+os.sep+str(project_id)
        config_yaml=create_dir_path+os.sep+"main.yaml"#项目初始数据存放的 yaml
        with open(config_yaml, 'r',encoding="utf-8") as file:
            all_config = yaml.safe_load(file)
        page_data=all_config['page_config']['dict']['1']['dict'][str(page_id)]['dict']['1']

        #读取保存html页面的路径
        html_dir=create_dir_path+os.sep+"html"+os.sep+str(page_id)
        try:os.makedirs(html_dir)
        except:pass
        now_html_mdt_path=html_dir+os.sep+'md5.yaml'
        try:
            with open(now_html_mdt_path, 'r',encoding="utf-8") as file:
                config = yaml.safe_load(file)
        except:
            config={'md5':''}
        check_md5=hashlib.md5(json.dumps(page_data).encode('utf-8')).hexdigest()
        html_path=html_dir+os.sep+"main.html"  
        if(check_md5!=config['md5']):
            config['md5']=check_md5
            with open(now_html_mdt_path, 'w') as file:  
                yaml.dump(config, file, default_flow_style=False, sort_keys=False)  
            # TODO：生成新的静态html文件
            with open(html_path,"w",encoding='utf-8')as f:
                f.write(tohtml(page_config=page_data,page_id=page_id,all_config=all_config).tohtml())
        with open(html_path,'r',encoding='utf-8')as f:
            # print(f.read())
            self.write(f.read())
    #保存项目
    def save_project(self,user_id,project_dir,project_id):
        global config_dct_data_
        # print(config_dct_data_)
        


        # 打开并读取YAML文件
        with open(config_yaml, 'w') as file:  
            yaml.dump(config_dct_data_[(user_id,project_dir,project_id)]['info'], file, default_flow_style=False, sort_keys=False)  
        print("保存成功")
        return {"type":"ok",'message':"保存成功"}
    def post(self):
        print("开始保存...")
        user_id=self.json_body.get("user_id")
        project_dir=self.json_body.get("project_dir")
        project_id=self.json_body.get("project_id")
        #todo 验证项目权限
        res=self.save_project(user_id,project_dir,project_id)
        self.write(res)
        #读取文件内容

        #匹配md5 如果一致则不更新静态文件 如果不一致则更新静态文件
    # http://127.0.0.1:9000/show_page?user_id=1&project_dir=3&project_id=104&page_id=1
def main():
    global ed_dct
    server_data_dct={
        #默认的处理
        "default":{
            "http":1
        },
    }#存放所有数据后台数据操作的 进程/函数的字典
    #初始化用户数据库
    user_db.db_init()
    #初始化项目目录数据路
    user_template_dir.db_init()
    #初始化组件目录数据库
    user_template.db_init()
    #编辑字段初始化
    from _base_tool.python.lhp_edit_data import edit_data_class
    #初始化base_js
    edit_data_class.init_base_js(base_config)
    edit_data_class.init_base_css(base_config)
    # ed=edit_data_class(base_config)
    # ed_dct['ed']=ed
    # global temp_info
    # temp_info=ed.获取基础组件数据()
    # print("ed.data",ed.data)
    # print("temp_info",temp_info)
    ttest().run()
    static_base_tuple=(r"/%s/(.*)"%base_config['static_path'], tornado.web.StaticFileHandler, {"path": base_config['static_dir']})
    # print(static_base_tuple)
    URL_lst=[
        (r'/login',login),#登录 
        (r'/login_in',login_in),#
        (r'/home',home),#编辑页面
        # (r'/test',test),#测试页面
        (r'/test.*',test2),#测试页面
        (r'/project',project),#项目选择页面
        (r'/template_all',template_all),#组件 相关设置
        # (r'/db',db),#数据库增删改查 
        (r"/websocket", WebSocketHandler), #websocket接口 
        (r'/check_login',check_login),#验证登录
        (r'/run_server',run_server),#运行当前的流程
        (r"/*",all_http),
        (r'/flow',flow),


######################----项目操作处理----######################
(r'/get_project_info',get_project_info),#获取 我的项目目录 和 
(r'/get_project_info2',get_project_info2),#获取 他人目录
(r'/change_project_dir1',change_project_dir1),#修改我的目录1 的名称
(r'/del_pro_dir1',del_pro_dir1),#删除我的项目目录
(r'/get_pro_editor',get_pro_editor),#获取项目参与者名单
(r'/change_pro_img',change_pro_img),#修改项目展示图片
(r'/get_pro_img/(.*)',get_pro_img),

(r'/get_other_project_dir',get_other_project_dir),#获取 他人项目 的所有项目目录
(r'/get_my_project_all',get_my_project_all),#获取我的项目XXX目录下的所有项目信息

(r'/get_other_project_all',get_other_project_all),#获取他人项目XXX目录下的所有项目信息
(r'/get_other_projects',get_other_projects),#获取他人项目 某#获取 他人项目 列表
(r'/create_project_dir',create_project_dir),#新建项目目录

(r'/del_project_dir',del_project_dir),#删除我的项目目录
(r'/create_project',create_project),#新建我的项目
(r'/save_project',save_project),#保存项目
(r'/del_project',del_project),#删除我的项目
(r'/change_project',change_project),#修改我的项目名称
(r'/project_user',project_user),#查看项目参与者目录



(r'/add_other_project',add_other_project),#添加别人参与我的项目
(r'/del_other_project',del_other_project),#删除别人参与我的项目
(r'/run_flow',run_flow),#运行流程
(r'/stop_flow',stop_flow),#结束流程
(r'/db_create_info',db_create_info),#复制表结构




##########################------组件库操作处理-------############################
        (r'/get_ui_dir1',get_ui_dir1),#获取用户前端目录1列表
        (r'/add_ui_dir1',add_ui_dir1),#添加用户目录1列表

        (r'/get_ui_dir2',get_ui_dir2),#获取用户前端目录2列表
        (r'/add_ui_dir2',add_ui_dir2),#添加用户目录1列表
        (r'/change_ui_dir1',change_ui_dir1),#修改用户目录1属性


        (r'/get_ui_temp',get_ui_temp),#获取用户的前端组件库组件列表
        (r'/add_ui_temp',add_ui_temp),#添添加前端组件
        (r'/change_ui_dir2',change_ui_dir2),#修改用户目录2属性

        (r'/get_ui_version',get_ui_version),#获取用户的前端组件库组件版本列表
        (r'/add_ui_version',add_ui_version),#添加前端组件版本
        (r'/change_ui_temp',change_ui_temp),#修改前端组件属性
        
        (r'/change_ui_version',change_ui_version),#修改前端组件版本属性
        (r'/update_ui_code',update_ui_code),#更新前端组件版本代码
        (r'/download_ui_code',download_ui_code),#下载代码
        (r'/start_download/(.*)',start_download),#下载代码

        (r'/get_flow_dir1',get_flow_dir1),#获取用户后端目录1列表
        (r'/add_flow_dir1',add_flow_dir1),#添加用户目录1列表

        (r'/get_flow_dir2',get_flow_dir2),#获取用户后端目录2列表
        (r'/add_flow_dir2',add_flow_dir2),#添加用户目录1列表
        (r'/change_flow_dir1',change_flow_dir1),#修改用户目录1属性
        
        (r'/get_flow_temp',get_flow_temp),#获取用户的后端组件库组件列表
        (r'/add_flow_temp',add_flow_temp),#添添加后端组件
        (r'/change_flow_dir2',change_flow_dir2),#修改用户目录2属性

        (r'/get_flow_version',get_flow_version),#获取用户的后端组件库组件版本列表
        (r'/add_flow_version',add_flow_version),#添加后端组件版本
        (r'/change_flow_temp',change_flow_temp),#修改后端组件属性

        (r'/change_flow_version',change_flow_version),#修改后端组件版本属性
        (r'/update_flow_code',update_flow_code),#更新后端组件版本代码
        (r'/download_flow_code',download_flow_code),#下载代码

        (r'/select_temp1',select_temp1),#查询前端组件库
        (r'/select_temp2',select_temp2),#查询前端组件库




    ############# 当前项目正在使用的
    (r'/paste_flow_dir1',paste_flow_dir1),#粘贴后端目录1
    (r'/paste_flow_dir2',paste_flow_dir2),#粘贴后按目录2
    (r'/paste_flow_temp',paste_flow_temp),#粘贴后端组件
    (r'/change_use_flow_version',change_use_flow_version),#修改后端组件版本


    ############# 当前项目正在使用的
    (r'/paste_page_dir1',paste_page_dir1),#粘贴后端目录1
    (r'/paste_page_dir2',paste_page_dir2),#粘贴后按目录2
    (r'/paste_page_temp',paste_page_temp),#粘贴后端组件
    (r'/change_use_page_version',change_use_page_version),#修改后端组件版本


    (r'/read_temp_png',read_temp_png),
    (r'/show_page',show_page),


        static_base_tuple
    ]
    set_http(process_type=True,url_lst=URL_lst,**base_config['process2_web_handle'])



if __name__=="__main__":
    main()
